Trying to track down the hows/whys of some of the recent changes led
me to the commits for this issue,
and I just happened to notice the bad changes to CHANGES below.  I
assume those removals were not intentional?

-Yonik


On Mon, Mar 9, 2015 at 12:29 PM,  <[email protected]> wrote:
> Author: noble
> Date: Mon Mar  9 16:29:08 2015
> New Revision: 1665295
>
> URL: http://svn.apache.org/r1665295
> Log:
> SOLR-7073:  Support adding a jar to a collections classpath
>
> Added:
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java
>       - copied, changed from r1664797, 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
>       - copied, changed from r1664797, 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/PluginBag.java
>       - copied unchanged from r1665076, 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/PluginBag.java
> Removed:
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandlerV2.java
> Modified:
>     lucene/dev/branches/branch_5x/   (props changed)
>     lucene/dev/branches/branch_5x/solr/   (props changed)
>     lucene/dev/branches/branch_5x/solr/CHANGES.txt   (contents, props changed)
>     lucene/dev/branches/branch_5x/solr/core/   (props changed)
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/JarRepository.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrCore.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/admin/AdminHandlers.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/OutputWriterTest.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/BlobStoreTestRequestHandler.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/core/TestDynamicLoading.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java
>     
> lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/search/TestStandardQParsers.java
>
> Modified: lucene/dev/branches/branch_5x/solr/CHANGES.txt
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/CHANGES.txt?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- lucene/dev/branches/branch_5x/solr/CHANGES.txt (original)
> +++ lucene/dev/branches/branch_5x/solr/CHANGES.txt Mon Mar  9 16:29:08 2015
> @@ -35,6 +35,9 @@ Upgrading from Solr 5.0
>  * The signature of SolrDispatchFilter.createCoreContainer() has changed to 
> take
>    (String,Properties) arguments
>
> +* Deprecated the 'lib' option added to create-requesthandler as part of 
> SOLR-6801 in 5.0 release.
> +  Please use the add-runtimelib command
> +
>  Detailed Change List
>  ----------------------
>
> @@ -87,20 +90,7 @@ New Features
>  * SOLR-7155,SOLR-7201: All SolrClient methods now take an optional 
> 'collection' argument
>    (Alan Woodward, Shawn Heisey)
>
> -* SOLR-6359: Allow number of logs and records kept by UpdateLog to be 
> configured
> -  (Ramkumar Aiyengar)
> -
> -* SOLR-7189: Allow DIH to extract content from embedded documents via Tika.
> -  (Tim Allison via shalin)
> -
> -* SOLR-6841: Visualize lucene segment information in Admin UI.
> -  (Alexey Kozhemiakin, Michal Bienkowski, hossman, Shawn Heisey, Varun 
> Thacker via shalin)
> -
> -* SOLR-5846: EnumField supports DocValues functionality. (Elran Dvir, shalin)
> -
> -* SOLR-4044: CloudSolrClient.connect() throws a more useful exception if the
> -  cluster is not ready, and can now take an optional timeout argument to wait
> -  for the cluster. (Alan Woodward, shalin, yonik, Mark Miller, Vitaliy 
> Zhovtyuk)
> +* SOLR-7073: Support adding a jar to a collections classpath (Noble Paul)
>
>  Bug Fixes
>  ----------------------
>
> Modified: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
>  (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
>  Mon Mar  9 16:29:08 2015
> @@ -39,7 +39,6 @@ import org.apache.solr.common.params.Upd
>  import org.apache.solr.core.CoreContainer;
>  import org.apache.solr.core.CoreDescriptor;
>  import org.apache.solr.core.DirectoryFactory.DirContext;
> -import org.apache.solr.core.RequestHandlers.LazyRequestHandlerWrapper;
>  import org.apache.solr.core.SolrCore;
>  import org.apache.solr.handler.ReplicationHandler;
>  import org.apache.solr.request.LocalSolrQueryRequest;
> @@ -146,9 +145,6 @@ public class RecoveryStrategy extends Th
>
>      // use rep handler directly, so we can do this sync rather than async
>      SolrRequestHandler handler = core.getRequestHandler(REPLICATION_HANDLER);
> -    if (handler instanceof LazyRequestHandlerWrapper) {
> -      handler = ((LazyRequestHandlerWrapper) handler).getWrappedHandler();
> -    }
>      ReplicationHandler replicationHandler = (ReplicationHandler) handler;
>
>      if (replicationHandler == null) {
>
> Modified: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
>  (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
>  Mon Mar  9 16:29:08 2015
> @@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory;
>  import java.io.File;
>  import java.util.ArrayList;
>  import java.util.Collection;
> -import java.util.HashMap;
>  import java.util.List;
>  import java.util.Locale;
>  import java.util.Map;
> @@ -108,13 +107,13 @@ public class CoreContainer {
>    public static final String COLLECTIONS_HANDLER_PATH = "/admin/collections";
>    public static final String INFO_HANDLER_PATH = "/admin/info";
>
> -  private Map<String, SolrRequestHandler> containerHandlers = new 
> HashMap<>();
> +  private PluginBag<SolrRequestHandler> containerHandlers = new 
> PluginBag<>(SolrRequestHandler.class, null);
>
>    public SolrRequestHandler getRequestHandler(String path) {
>      return RequestHandlerBase.getRequestHandler(path, containerHandlers);
>    }
>
> -  public Map<String, SolrRequestHandler> getRequestHandlers(){
> +  public PluginBag<SolrRequestHandler> getRequestHandlers() {
>      return this.containerHandlers;
>    }
>
>
> Copied: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java
>  (from r1664797, 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java)
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java?p2=lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java&p1=lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java&r1=1664797&r2=1665295&rev=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java 
> (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/ImplicitPlugins.java
>  Mon Mar  9 16:29:08 2015
> @@ -34,6 +34,7 @@ import org.apache.solr.handler.admin.Log
>  import org.apache.solr.handler.admin.LukeRequestHandler;
>  import org.apache.solr.handler.admin.PluginInfoHandler;
>  import org.apache.solr.handler.admin.PropertiesRequestHandler;
> +import org.apache.solr.handler.admin.SegmentsInfoRequestHandler;
>  import org.apache.solr.handler.admin.ShowFileRequestHandler;
>  import org.apache.solr.handler.admin.SolrInfoMBeanHandler;
>  import org.apache.solr.handler.admin.SystemInfoHandler;
> @@ -80,6 +81,7 @@ public class ImplicitPlugins {
>      PluginInfo ping = getReqHandlerInfo("/admin/ping", 
> PingRequestHandler.class, null);
>      ping.initArgs.add(INVARIANTS, new NamedList<>(makeMap("echoParams", 
> "all", "q", "solrpingquery")));
>      implicits.add(ping);
> +    implicits.add(getReqHandlerInfo("/admin/segments", 
> SegmentsInfoRequestHandler.class, null));
>      return implicits;
>    }
>
>
> Modified: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/JarRepository.java
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/JarRepository.java?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/JarRepository.java
>  (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/JarRepository.java
>  Mon Mar  9 16:29:08 2015
> @@ -24,7 +24,6 @@ import java.io.ByteArrayInputStream;
>  import java.io.IOException;
>  import java.nio.ByteBuffer;
>  import java.util.ArrayList;
> -import java.util.Collection;
>  import java.util.Collections;
>  import java.util.HashSet;
>  import java.util.List;
> @@ -43,7 +42,6 @@ import org.apache.solr.common.cloud.Clus
>  import org.apache.solr.common.cloud.DocCollection;
>  import org.apache.solr.common.cloud.Replica;
>  import org.apache.solr.common.cloud.Slice;
> -import org.apache.solr.common.cloud.ZkCoreNodeProps;
>  import org.apache.solr.common.cloud.ZkStateReader;
>  import org.apache.solr.handler.admin.CollectionsHandler;
>  import org.apache.solr.util.SimplePostTool;
> @@ -76,37 +74,16 @@ public class JarRepository {
>    }
>
>    /**
> -   * Returns the contents of a jar and increments a reference count. Please 
> return the same object to decerease the refcount
> +   * Returns the contents of a jar and increments a reference count. Please 
> return the same object to decrease the refcount
>     *
>     * @param key it is a combination of blobname and version like 
> blobName/version
>     * @return The reference of a jar
>     */
> -  public JarContentRef getJarIncRef(String key) throws IOException {
> +  public JarContentRef getJarIncRef(String key) {
>      JarContent jar = jars.get(key);
>      if (jar == null) {
>        if (this.coreContainer.isZooKeeperAware()) {
> -        ZkStateReader zkStateReader = 
> this.coreContainer.getZkController().getZkStateReader();
> -        ClusterState cs = zkStateReader.getClusterState();
> -        DocCollection coll = 
> cs.getCollectionOrNull(CollectionsHandler.SYSTEM_COLL);
> -        if (coll == null) throw new SolrException(SERVICE_UNAVAILABLE, 
> ".system collection not available");
> -        ArrayList<Slice> slices = new ArrayList<>(coll.getActiveSlices());
> -        if (slices.isEmpty()) throw new SolrException(SERVICE_UNAVAILABLE, 
> "No active slices for .system collection");
> -        Collections.shuffle(slices, RANDOM); //do load balancing
> -
> -        Replica replica = null;
> -        for (Slice slice : slices)  {
> -          List<Replica> replicas = new 
> ArrayList<>(slice.getReplicasMap().values());
> -          Collections.shuffle(replicas, RANDOM);
> -          for (Replica r : replicas) {
> -            if 
> (ZkStateReader.ACTIVE.equals(r.getStr(ZkStateReader.STATE_PROP))) {
> -              replica = r;
> -              break;
> -            }
> -          }
> -        }
> -        if (replica == null) {
> -          throw new SolrException(SERVICE_UNAVAILABLE, ".no active replica 
> available for .system collection");
> -        }
> +        Replica replica = getSystemCollReplica();
>          String url = replica.getStr(BASE_URL_PROP) + "/.system/blob/" + key 
> + "?wt=filestream";
>
>          HttpClient httpClient = 
> coreContainer.getUpdateShardHandler().getHttpClient();
> @@ -119,6 +96,12 @@ public class JarRepository {
>              throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "no 
> such blob or version available: " + key);
>            }
>            b = 
> SimplePostTool.inputStreamToByteArray(entity.getEntity().getContent());
> +        } catch (Exception e) {
> +          if (e instanceof SolrException) {
> +            throw (SolrException) e;
> +          } else {
> +            throw new SolrException(SolrException.ErrorCode.NOT_FOUND, 
> "could not load : " + key, e);
> +          }
>          } finally {
>            httpGet.releaseConnection();
>          }
> @@ -138,6 +121,36 @@ public class JarRepository {
>
>    }
>
> +  private Replica getSystemCollReplica() {
> +    ZkStateReader zkStateReader = 
> this.coreContainer.getZkController().getZkStateReader();
> +    ClusterState cs = zkStateReader.getClusterState();
> +    DocCollection coll = 
> cs.getCollectionOrNull(CollectionsHandler.SYSTEM_COLL);
> +    if (coll == null) throw new SolrException(SERVICE_UNAVAILABLE, ".system 
> collection not available");
> +    ArrayList<Slice> slices = new ArrayList<>(coll.getActiveSlices());
> +    if (slices.isEmpty()) throw new SolrException(SERVICE_UNAVAILABLE, "No 
> active slices for .system collection");
> +    Collections.shuffle(slices, RANDOM); //do load balancing
> +
> +    Replica replica = null;
> +    for (Slice slice : slices) {
> +      List<Replica> replicas = new 
> ArrayList<>(slice.getReplicasMap().values());
> +      Collections.shuffle(replicas, RANDOM);
> +      for (Replica r : replicas) {
> +        if (ZkStateReader.ACTIVE.equals(r.getStr(ZkStateReader.STATE_PROP))) 
> {
> +          
> if(zkStateReader.getClusterState().getLiveNodes().contains(r.get(ZkStateReader.NODE_NAME_PROP))){
> +            replica = r;
> +            break;
> +          } else {
> +            log.info("replica {} says it is active but not a member of live 
> nodes", r.get(ZkStateReader.NODE_NAME_PROP));
> +          }
> +        }
> +      }
> +    }
> +    if (replica == null) {
> +      throw new SolrException(SERVICE_UNAVAILABLE, ".no active replica 
> available for .system collection");
> +    }
> +    return replica;
> +  }
> +
>    /**
>     * This is to decrement a ref count
>     *
>
> Copied: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
>  (from r1664797, 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/MemClassLoader.java)
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MemClassLoader.java?p2=lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MemClassLoader.java&p1=lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/MemClassLoader.java&r1=1664797&r2=1665295&rev=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/MemClassLoader.java 
> (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
>  Mon Mar  9 16:29:08 2015
> @@ -29,7 +29,6 @@ import java.util.ArrayList;
>  import java.util.HashMap;
>  import java.util.List;
>  import java.util.Map;
> -import java.util.concurrent.ConcurrentHashMap;
>  import java.util.concurrent.atomic.AtomicReference;
>
>  import org.apache.lucene.analysis.util.ResourceLoader;
> @@ -42,11 +41,11 @@ public class MemClassLoader extends Clas
>    static final Logger log =  LoggerFactory.getLogger(MemClassLoader.class);
>    private boolean allJarsLoaded = false;
>    private final SolrResourceLoader parentLoader;
> -  private List<PluginRegistry.RuntimeLib> libs = new ArrayList<>();
> +  private List<PluginBag.RuntimeLib> libs = new ArrayList<>();
>    private Map<String, Class> classCache = new HashMap<>();
>
>
> -  public MemClassLoader(List<PluginRegistry.RuntimeLib> libs, 
> SolrResourceLoader resourceLoader) {
> +  public MemClassLoader(List<PluginBag.RuntimeLib> libs, SolrResourceLoader 
> resourceLoader) {
>      this.parentLoader = resourceLoader;
>      this.libs = libs;
>    }
> @@ -55,7 +54,7 @@ public class MemClassLoader extends Clas
>    public synchronized void loadJars() {
>      if (allJarsLoaded) return;
>
> -    for (PluginRegistry.RuntimeLib lib : libs) {
> +    for (PluginBag.RuntimeLib lib : libs) {
>        try {
>          lib.loadJar();
>        } catch (Exception exception) {
> @@ -113,7 +112,7 @@ public class MemClassLoader extends Clas
>
>      String path = name.replace('.', '/').concat(".class");
>      ByteBuffer buf = null;
> -    for (PluginRegistry.RuntimeLib lib : libs) {
> +    for (PluginBag.RuntimeLib lib : libs) {
>        try {
>          buf = lib.getFileContent(path);
>          if (buf != null) {
> @@ -130,7 +129,7 @@ public class MemClassLoader extends Clas
>
>    @Override
>    public void close() throws Exception {
> -    for (PluginRegistry.RuntimeLib lib : libs) {
> +    for (PluginBag.RuntimeLib lib : libs) {
>        try {
>          lib.close();
>        } catch (Exception e) {
>
> Modified: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RequestHandlers.java?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
>  (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
>  Mon Mar  9 16:29:08 2015
> @@ -17,41 +17,14 @@
>
>  package org.apache.solr.core;
>
> -import java.io.Closeable;
> -import java.io.IOException;
> -import java.lang.reflect.Constructor;
> -import java.net.MalformedURLException;
> -import java.net.URL;
> -import java.nio.ByteBuffer;
> -import java.security.BasicPermission;
> -import java.security.CodeSource;
> -import java.security.Permissions;
> -import java.security.ProtectionDomain;
> -import java.security.SecureClassLoader;
> -import java.security.cert.Certificate;
> -import java.text.MessageFormat;
>  import java.util.ArrayList;
>  import java.util.Collections;
> -import java.util.HashMap;
>  import java.util.LinkedHashMap;
>  import java.util.List;
>  import java.util.Map;
> -import java.util.concurrent.ConcurrentHashMap;
> -import java.util.jar.JarFile;
>
> -import org.apache.solr.client.solrj.SolrRequest;
> -import org.apache.solr.common.SolrException;
> -import org.apache.solr.common.SolrException.ErrorCode;
> -import org.apache.solr.common.util.NamedList;
> -import org.apache.solr.common.util.SimpleOrderedMap;
>  import org.apache.solr.common.util.StrUtils;
> -import org.apache.solr.handler.RequestHandlerBase;
> -import org.apache.solr.request.SolrQueryRequest;
> -import org.apache.solr.request.SolrQueryRequestBase;
>  import org.apache.solr.request.SolrRequestHandler;
> -import org.apache.solr.response.SolrQueryResponse;
> -import org.apache.solr.util.plugin.PluginInfoInitialized;
> -import org.apache.solr.util.plugin.SolrCoreAware;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
>
> @@ -61,13 +34,8 @@ public final class RequestHandlers {
>    public static Logger log = LoggerFactory.getLogger(RequestHandlers.class);
>
>    protected final SolrCore core;
> -  // Use a synchronized map - since the handlers can be changed at runtime,
> -  // the map implementation should be thread safe
> -  private final Map<String, SolrRequestHandler> handlers =
> -      new ConcurrentHashMap<>() ;
> -  private final Map<String, SolrRequestHandler> immutableHandlers = 
> Collections.unmodifiableMap(handlers) ;
>
> -  public static final boolean disableExternalLib = 
> Boolean.parseBoolean(System.getProperty("disable.external.lib", "false"));
> +  final PluginBag<SolrRequestHandler> handlers;
>
>    /**
>     * Trim the trailing '/' if it's there, and convert null to empty string.
> @@ -89,6 +57,7 @@ public final class RequestHandlers {
>
>    public RequestHandlers(SolrCore core) {
>        this.core = core;
> +    handlers =  new PluginBag<>(SolrRequestHandler.class, core);
>    }
>
>    /**
> @@ -99,17 +68,6 @@ public final class RequestHandlers {
>    }
>
>    /**
> -   * @return a Map of all registered handlers of the specified type.
> -   */
> -  public <T extends SolrRequestHandler> Map<String,T> getAll(Class<T> clazz) 
> {
> -    Map<String,T> result = new HashMap<>(7);
> -    for (Map.Entry<String,SolrRequestHandler> e : handlers.entrySet()) {
> -      if(clazz.isInstance(e.getValue())) result.put(e.getKey(), 
> clazz.cast(e.getValue()));
> -    }
> -    return result;
> -  }
> -
> -  /**
>     * Handlers must be initialized before calling this function.  As soon as 
> this is
>     * called, the handler can immediately accept requests.
>     *
> @@ -118,22 +76,20 @@ public final class RequestHandlers {
>     * @return the previous handler at the given path or null
>     */
>    public SolrRequestHandler register( String handlerName, SolrRequestHandler 
> handler ) {
> -    String norm = normalize( handlerName );
> +    String norm = normalize(handlerName);
>      if (handler == null) {
>        return handlers.remove(norm);
>      }
> -    SolrRequestHandler old = handlers.put(norm, handler);
> -    if (0 != norm.length() && handler instanceof SolrInfoMBean) {
> -      core.getInfoRegistry().put(handlerName, handler);
> -    }
> -    return old;
> +    return handlers.put(norm, handler);
> +//    return register(handlerName, new PluginRegistry.PluginHolder<>(null, 
> handler));
>    }
>
> +
>    /**
>     * Returns an unmodifiable Map containing the registered handlers
>     */
> -  public Map<String,SolrRequestHandler> getRequestHandlers() {
> -    return immutableHandlers;
> +  public PluginBag<SolrRequestHandler> getRequestHandlers() {
> +    return handlers;
>    }
>
>
> @@ -157,66 +113,28 @@ public final class RequestHandlers {
>     * Handlers will be registered and initialized in the order they appear in 
> solrconfig.xml
>     */
>
> -  void initHandlersFromConfig(SolrConfig config){
> -    List<PluginInfo> implicits = PluginsRegistry.getHandlers(core);
> +  void initHandlersFromConfig(SolrConfig config) {
> +    List<PluginInfo> implicits = ImplicitPlugins.getHandlers(core);
>      // use link map so we iterate in the same order
> -    Map<PluginInfo,SolrRequestHandler> handlers = new LinkedHashMap<>();
>      Map<String, PluginInfo> infoMap= new LinkedHashMap<>();
>      //deduping implicit and explicit requesthandlers
>      for (PluginInfo info : implicits) infoMap.put(info.name,info);
>      for (PluginInfo info : 
> config.getPluginInfos(SolrRequestHandler.class.getName())) 
> infoMap.put(info.name, info);
>      ArrayList<PluginInfo> infos = new ArrayList<>(infoMap.values());
> +
> +    List<PluginInfo> modifiedInfos = new ArrayList<>();
>      for (PluginInfo info : infos) {
> -      try {
> -        SolrRequestHandler requestHandler;
> -        String startup = info.attributes.get("startup");
> -        String lib = info.attributes.get("lib");
> -        if (lib != null) {
> -          requestHandler = new DynamicLazyRequestHandlerWrapper(core);
> -        } else if (startup != null) {
> -          if ("lazy".equals(startup)) {
> -            log.info("adding lazy requestHandler: " + info.className);
> -            requestHandler = new LazyRequestHandlerWrapper(core);
> -          } else {
> -            throw new Exception("Unknown startup value: '" + startup + "' 
> for: " + info.className);
> -          }
> -        } else {
> -          requestHandler = core.createRequestHandler(info.className);
> -        }
> -        if (requestHandler instanceof RequestHandlerBase) 
> ((RequestHandlerBase) requestHandler).setPluginInfo(info);
> -
> -        handlers.put(info, requestHandler);
> -        SolrRequestHandler old = register(info.name, requestHandler);
> -        if (old != null) {
> -          log.warn("Multiple requestHandler registered to the same name: " + 
> info.name + " ignoring: " + old.getClass().getName());
> -        }
> -        if (info.isDefault()) {
> -          old = register("", requestHandler);
> -          if (old != null) log.warn("Multiple default requestHandler 
> registered" + " ignoring: " + old.getClass().getName());
> -        }
> -        log.info("created " + info.name + ": " + info.className);
> -      } catch (Exception ex) {
> -          throw new SolrException
> -            (ErrorCode.SERVER_ERROR, "RequestHandler init failure", ex);
> -      }
> +      modifiedInfos.add(applyInitParams(config, info));
>      }
> -
> -    // we've now registered all handlers, time to init them in the same order
> -    for (Map.Entry<PluginInfo,SolrRequestHandler> entry : 
> handlers.entrySet()) {
> -      PluginInfo info = entry.getKey();
> -      SolrRequestHandler requestHandler = entry.getValue();
> -      info = applyInitParams(config, info);
> -      if (requestHandler instanceof PluginInfoInitialized) {
> -       ((PluginInfoInitialized) requestHandler).init(info);
> -      } else{
> -        requestHandler.init(info.initArgs);
> +    handlers.init(Collections.EMPTY_MAP,core, modifiedInfos);
> +    handlers.alias(handlers.getDefault(), "");
> +    log.info("Registered paths: {}" , StrUtils.join(new 
> ArrayList<>(handlers.keySet()) , ',' ));
> +    if(!handlers.alias( "/select","")){
> +      if(!handlers.alias( "standard","")){
> +        log.warn("no default request handler is registered (either '/select' 
> or 'standard')");
>        }
>      }
>
> -    if(get("") == null) register("", get("/select"));//defacto default 
> handler
> -    if(get("") == null) register("", get("standard"));//old default handler 
> name; TODO remove?
> -    if(get("") == null)
> -      log.warn("no default request handler is registered (either '/select' 
> or 'standard')");
>    }
>
>    private PluginInfo applyInitParams(SolrConfig config, PluginInfo info) {
> @@ -239,328 +157,8 @@ public final class RequestHandlers {
>      return info;
>    }
>
> -
> -  /**
> -   * The <code>LazyRequestHandlerWrapper</code> wraps any {@link 
> SolrRequestHandler}.
> -   * Rather then instantiate and initialize the handler on startup, this 
> wrapper waits
> -   * until it is actually called.  This should only be used for handlers 
> that are
> -   * unlikely to be used in the normal lifecycle.
> -   *
> -   * You can enable lazy loading in solrconfig.xml using:
> -   *
> -   * <pre>
> -   *  &lt;requestHandler name="..." class="..." startup="lazy"&gt;
> -   *    ...
> -   *  &lt;/requestHandler&gt;
> -   * </pre>
> -   *
> -   * This is a private class - if there is a real need for it to be public, 
> it could
> -   * move
> -   *
> -   * @since solr 1.2
> -   */
> -  public static class LazyRequestHandlerWrapper implements 
> SolrRequestHandler, AutoCloseable, PluginInfoInitialized {
> -    private final SolrCore core;
> -    String _className;
> -    SolrRequestHandler _handler;
> -    PluginInfo _pluginInfo;
> -
> -    public LazyRequestHandlerWrapper(SolrCore core) {
> -      this.core = core;
> -      _handler = null; // don't initialize
> -    }
> -
> -    @Override
> -    public void init(NamedList args) {
> -    }
> -
> -    /**
> -     * Wait for the first request before initializing the wrapped handler
> -     */
> -    @Override
> -    public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
> -      SolrRequestHandler handler = _handler;
> -      if (handler == null) {
> -        handler = getWrappedHandler();
> -      }
> -      handler.handleRequest(req, rsp);
> -    }
> -
> -    public synchronized SolrRequestHandler getWrappedHandler() {
> -      if (_handler == null) {
> -        try {
> -          SolrRequestHandler handler = createRequestHandler();
> -          if (handler instanceof PluginInfoInitialized) {
> -            ((PluginInfoInitialized) handler).init(_pluginInfo);
> -          } else {
> -            handler.init(_pluginInfo.initArgs);
> -          }
> -
> -          if (handler instanceof PluginInfoInitialized) {
> -            ((PluginInfoInitialized) handler).init(_pluginInfo);
> -          } else {
> -            handler.init(_pluginInfo.initArgs);
> -          }
> -
> -
> -          if (handler instanceof SolrCoreAware) {
> -            ((SolrCoreAware) handler).inform(core);
> -          }
> -          if (handler instanceof RequestHandlerBase) ((RequestHandlerBase) 
> handler).setPluginInfo(_pluginInfo);
> -          _handler = handler;
> -        } catch (Exception ex) {
> -          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, 
> "lazy loading error", ex);
> -        }
> -      }
> -      return _handler;
> -    }
> -
> -    protected SolrRequestHandler createRequestHandler() {
> -      return core.createRequestHandler(_className);
> -    }
> -
> -    public String getHandlerClass() {
> -      return _className;
> -    }
> -
> -    //////////////////////// SolrInfoMBeans methods //////////////////////
> -
> -    @Override
> -    public String getName() {
> -      return "Lazy[" + _className + "]";
> -    }
> -
> -    @Override
> -    public String getDescription() {
> -      if (_handler == null) {
> -        return getName();
> -      }
> -      return _handler.getDescription();
> -    }
> -
> -    @Override
> -    public String getVersion() {
> -      if (_handler != null) {
> -        return _handler.getVersion();
> -      }
> -      return null;
> -    }
> -
> -    @Override
> -    public String getSource() {
> -      return null;
> -    }
> -
> -    @Override
> -    public URL[] getDocs() {
> -      if (_handler == null) {
> -        return null;
> -      }
> -      return _handler.getDocs();
> -    }
> -
> -    @Override
> -    public Category getCategory() {
> -      return Category.QUERYHANDLER;
> -    }
> -
> -    @Override
> -    public NamedList getStatistics() {
> -      if (_handler != null) {
> -        return _handler.getStatistics();
> -      }
> -      NamedList<String> lst = new SimpleOrderedMap<>();
> -      lst.add("note", "not initialized yet");
> -      return lst;
> -    }
> -
> -    @Override
> -    public void close() throws Exception {
> -      if (_handler == null) return;
> -      if (_handler instanceof AutoCloseable && !(_handler instanceof 
> DynamicLazyRequestHandlerWrapper)) {
> -        ((AutoCloseable) _handler).close();
> -      }
> -    }
> -
> -    @Override
> -    public void init(PluginInfo info) {
> -      _pluginInfo = info;
> -      _className = info.className;
> -    }
> -  }
> -
> -  public static class DynamicLazyRequestHandlerWrapper extends 
> LazyRequestHandlerWrapper {
> -    private String lib;
> -    private String key;
> -    private String version;
> -    private CoreContainer coreContainer;
> -    private SolrResourceLoader solrResourceLoader;
> -    private MemClassLoader classLoader;
> -    private boolean _closed = false;
> -    boolean unrecoverable = false;
> -    String errMsg = null;
> -    private Exception exception;
> -
> -
> -    public DynamicLazyRequestHandlerWrapper(SolrCore core) {
> -      super(core);
> -      this.coreContainer = core.getCoreDescriptor().getCoreContainer();
> -      this.solrResourceLoader = core.getResourceLoader();
> -
> -    }
> -
> -    @Override
> -    public void init(PluginInfo info) {
> -      super.init(info);
> -      this.lib = _pluginInfo.attributes.get("lib");
> -
> -      if (disableExternalLib) {
> -        errMsg = "ERROR external library loading is disabled";
> -        unrecoverable = true;
> -        _handler = this;
> -        log.error(errMsg);
> -        return;
> -      }
> -
> -      if (_pluginInfo.attributes.get("version") == null) {
> -        errMsg = "ERROR 'lib' attribute must be accompanied with version 
> also";
> -        unrecoverable = true;
> -        _handler = this;
> -        log.error(errMsg);
> -        return;
> -      }
> -      version = String.valueOf(_pluginInfo.attributes.get("version"));
> -      classLoader = new MemClassLoader(this);
> -    }
> -
> -    @Override
> -    public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
> -      if (unrecoverable) {
> -        rsp.add("error", errMsg);
> -        if (exception != null) rsp.setException(exception);
> -        return;
> -      }
> -      try {
> -        classLoader.checkJarAvailable();
> -      } catch (SolrException e) {
> -        rsp.add("error", "Jar could not be loaded");
> -        rsp.setException(e);
> -        return;
> -      } catch (IOException e) {
> -        unrecoverable = true;
> -        errMsg = "Could not load jar";
> -        exception = e;
> -        handleRequest(req, rsp);
> -        return;
> -      }
> -
> -      super.handleRequest(req, rsp);
> -    }
> -
> -    @Override
> -    protected SolrRequestHandler createRequestHandler() {
> -      try {
> -        Class clazz = classLoader.findClass(_className);
> -        Constructor<?>[] cons = clazz.getConstructors();
> -        for (Constructor<?> con : cons) {
> -          Class<?>[] types = con.getParameterTypes();
> -          if (types.length == 1 && types[0] == SolrCore.class) {
> -            return SolrRequestHandler.class.cast(con.newInstance(this));
> -          }
> -        }
> -        return (SolrRequestHandler) clazz.newInstance();
> -      } catch (Exception e) {
> -        unrecoverable = true;
> -        errMsg = MessageFormat.format("class {0} could not be loaded ", 
> _className);
> -        this.exception = e;
> -        return this;
> -
> -      }
> -
> -    }
> -
> -    @Override
> -    public void close() throws Exception {
> -      super.close();
> -      if (_closed) return;
> -      if (classLoader != null) classLoader.releaseJar();
> -      _closed = true;
> -    }
> -  }
> -
> -
> -  public static class MemClassLoader extends ClassLoader {
> -    private JarRepository.JarContentRef jarContent;
> -    private final DynamicLazyRequestHandlerWrapper handlerWrapper;
> -
> -    public MemClassLoader(DynamicLazyRequestHandlerWrapper handlerWrapper) {
> -      super(handlerWrapper.solrResourceLoader.classLoader);
> -      this.handlerWrapper = handlerWrapper;
> -
> -    }
> -
> -    boolean checkJarAvailable() throws IOException {
> -      if (jarContent != null) return true;
> -
> -      try {
> -        synchronized (this) {
> -          jarContent = 
> handlerWrapper.coreContainer.getJarRepository().getJarIncRef(handlerWrapper.lib
>  + "/" + handlerWrapper.version);
> -          return true;
> -        }
> -      } catch (SolrException se) {
> -        throw se;
> -      }
> -
> -    }
> -
> -    @Override
> -    protected Class<?> findClass(String name) throws ClassNotFoundException {
> -      try {
> -        return super.findClass(name);
> -      } catch (ClassNotFoundException e) {
> -        String path = name.replace('.', '/').concat(".class");
> -        ByteBuffer buf = null;
> -        try {
> -          if (jarContent == null) checkJarAvailable();
> -          buf = jarContent.jar.getFileContent(path);
> -          if (buf == null) throw new ClassNotFoundException("class not found 
> in loaded jar" + name);
> -        } catch (IOException e1) {
> -          throw new ClassNotFoundException("class not found " + name, e1);
> -
> -        }
> -
> -        ProtectionDomain defaultDomain = null;
> -
> -        //using the default protection domain, with no permissions
> -        try {
> -          defaultDomain = new ProtectionDomain(new CodeSource(new 
> URL("http://localhost/.system/blob/"; + handlerWrapper.lib), (Certificate[]) 
> null),
> -              null);
> -        } catch (MalformedURLException e1) {
> -          //should not happen
> -        }
> -        return defineClass(name, buf.array(), buf.arrayOffset(), 
> buf.limit(), defaultDomain);
> -      }
> -    }
> -
> -
> -    private void releaseJar() {
> -      
> handlerWrapper.coreContainer.getJarRepository().decrementJarRefCount(jarContent);
> -    }
> -
> -  }
> -
>    public void close() {
> -    for (Map.Entry<String, SolrRequestHandler> e : handlers.entrySet()) {
> -      if (e.getValue() instanceof AutoCloseable) {
> -        try {
> -          ((AutoCloseable) e.getValue()).close();
> -        } catch (Exception exp) {
> -          log.error("Error closing requestHandler " + e.getKey(), exp);
> -        }
> -      }
> -
> -    }
> -
> +    handlers.close();
>    }
>  }
>
>
> Modified: 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
> URL: 
> http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrConfig.java?rev=1665295&r1=1665294&r2=1665295&view=diff
> ==============================================================================
> --- 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
>  (original)
> +++ 
> lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
>  Mon Mar  9 16:29:08 2015
> @@ -46,8 +46,6 @@ import org.apache.solr.update.processor.
>  import org.apache.solr.util.DOMUtil;
>  import org.apache.solr.util.FileUtils;
>  import org.apache.solr.util.RegexFileFilter;
> -import org.apache.zookeeper.KeeperException;
> -import org.apache.zookeeper.data.Stat;
>  import org.noggit.JSONParser;
>  import org.noggit.ObjectBuilder;
>  import org.slf4j.Logger;
> @@ -77,6 +75,7 @@ import java.util.Set;
>  import java.util.regex.Matcher;
>  import java.util.regex.Pattern;
>
> +import static org.apache.solr.core.SolrConfig.PluginOpts.LAZY;
>  import static org.apache.solr.core.SolrConfig.PluginOpts.MULTI_OK;
>  import static org.apache.solr.core.SolrConfig.PluginOpts.NOOP;
>  import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_CLASS;
> @@ -99,6 +98,7 @@ public class SolrConfig extends Config i
>      MULTI_OK,
>      REQUIRE_NAME,
>      REQUIRE_CLASS,
> +    LAZY,
>      // EnumSet.of and/or EnumSet.copyOf(Collection) are anoying
>      // because of type determination
>      NOOP
> @@ -308,9 +308,9 @@ public class SolrConfig extends Config i
>    }
>
>    public static final  List<SolrPluginInfo> plugins = 
> ImmutableList.<SolrPluginInfo>builder()
> -      .add(new SolrPluginInfo(SolrRequestHandler.class, 
> SolrRequestHandler.TYPE, REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
> +      .add(new SolrPluginInfo(SolrRequestHandler.class, 
> SolrRequestHandler.TYPE, REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK, LAZY))
>        .add(new SolrPluginInfo(QParserPlugin.class, "queryParser", 
> REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
> -      .add(new SolrPluginInfo(QueryResponseWriter.class, 
> "queryResponseWriter", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
> +      .add(new SolrPluginInfo(QueryResponseWriter.class, 
> "queryResponseWriter", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK, LAZY))
>        .add(new SolrPluginInfo(ValueSourceParser.class, "valueSourceParser", 
> REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
>        .add(new SolrPluginInfo(TransformerFactory.class, "transformer", 
> REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
>        .add(new SolrPluginInfo(SearchComponent.class, "searchComponent", 
> REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
> @@ -319,6 +319,7 @@ public class SolrConfig extends Config i
>        // and even then -- only if there is a single SpellCheckComponent
>        // because of queryConverter.setIndexAnalyzer
>        .add(new SolrPluginInfo(QueryConverter.class, "queryConverter", 
> REQUIRE_NAME, REQUIRE_CLASS))
> +      .add(new SolrPluginInfo(PluginBag.RuntimeLib.class, "runtimeLib", 
> REQUIRE_NAME, MULTI_OK))
>        // this is hackish, since it picks up all SolrEventListeners,
>        // regardless of when/how/why they are used (or even if they are
>        // declared outside of the appropriate context) but there's no nice
> @@ -335,10 +336,11 @@ public class SolrConfig extends Config i
>        .add(new SolrPluginInfo(InitParams.class, InitParams.TYPE, MULTI_OK))
>        .add(new SolrPluginInfo(StatsCache.class, "statsCache", REQUIRE_CLASS))
>        .build();
> -  private static final Map<String, SolrPluginInfo> clsVsInfo = new 
> HashMap<>();
> -
> +  public static final Map<String, SolrPluginInfo> classVsSolrPluginInfo;
>    static {
> -    for (SolrPluginInfo plugin : plugins) 
> clsVsInfo.put(plugin.clazz.getName(), plugin);
> +    Map<String, SolrPluginInfo> map = new HashMap<>();
> +    for (SolrPluginInfo plugin : plugins) map.put(plugin.clazz.getName(), 
> plugin);
> +    classVsSolrPluginInfo = Collections.unmodifiableMap(map);
>    }
>
>    public static class SolrPluginInfo{
> @@ -646,7 +648,7 @@ public class SolrConfig extends Config i
>     */
>    public List<PluginInfo> getPluginInfos(String type) {
>      List<PluginInfo> result = pluginStore.get(type);
> -    SolrPluginInfo info = clsVsInfo.get(type);
> +    SolrPluginInfo info = classVsSolrPluginInfo.get(type);
>      if (info != null && info.options.contains(REQUIRE_NAME)) {
>        Map<String, Map> infos = overlay.getNamedPlugins(info.tag);
>        if (!infos.isEmpty()) {
> @@ -676,14 +678,14 @@ public class SolrConfig extends Config i
>    private void initLibs() {
>      NodeList nodes = (NodeList) evaluate("lib", XPathConstants.NODESET);
>      if (nodes == null || nodes.getLength() == 0) return;
> -
> +
>      log.info("Adding specified lib dirs to ClassLoader");
>      SolrResourceLoader loader = getResourceLoader();
> -
> +
>      try {
>        for (int i = 0; i < nodes.getLength(); i++) {
>          Node node = nodes.item(i);
> -
> +
>          String baseDir = DOMUtil.getAttr(node, "dir");
>          String path = DOMUtil.getAttr(node, "path");
>          if (null != baseDir) {
> @@ -708,7 +710,7 @@ public class SolrConfig extends Config i
>        loader.reloadLuceneSPI();
>      }
>    }
> -
> +
>    public int getMultipartUploadLimitKB() {
>      return multipartUploadLimitKB;
>    }
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to