仅使用特定文件夹中的类创建类加载器

时间:2019-07-03 07:14:41

标签: java classloader urlclassloader

我想使用specific ClassLoaderScriptEngineManager中加载特定的jars

  

此构造函数使用服务提供者机制加载对给定ClassLoader可见的ScriptEngineFactory实现。

我尝试创建Classloader

时遇到的问题
File file = new File("c:\\myclasses\\");

try {
// Convert File to a URL
URL url = file.toURI().toURL();          // file:/c:/myclasses/
URL[] urls = new URL[]{url};

// Create a new class loader with the directory
ClassLoader cl = new URLClassLoader(urls)

我也正在上课,例如Spring

 Class cls1 = cl.loadClass("org.springframework.http.HttpStatus");

如何仅使用特定文件夹的类创建干净的类加载器?

编辑

如果不可能,我可以在groovy脚本中使用与Rhino的ClassShutter等效的东西

private static void setJavaClassesVisibleInvisibleSandbox(Context cx)
 {
  cx.setClassShutter(new ClassShutter()
   {
      public boolean visibleToScripts(String className)
      {
          // No Java classes allowed inside scripts

编辑

当尝试使用@ Vinz243 CustomClassLoader解决方案无法从特定文件夹加载类文件或jar文件的类时,甚至尝试了rt.jar

java.lang.SecurityException: Prohibited package name: java.lang
    at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at com.CustomClassLoader.loadClass(CustomClassLoader.java:15)

1 个答案:

答案 0 :(得分:3)

如javadoc中所指定:

  

public URLClassLoader(URL[] urls)

     

使用默认的委托父ClassLoade r为指定的URL 构造一个新的URLClassLoader。在首先在父类加载器中搜索后,将以为类和资源指定的顺序搜索URL。假定任何以“ /”结尾的URL均指向目录。否则,假定该URL指向将要根据需要下载并打开的JAR文件。

因此,您可以尝试扩展ClassLoader,因为负责加载父类的机制位于java.lang.ClassLoader#loadClass(java.lang.String, boolean)

内部
    try {
        if (parent != null) {
            c = parent.loadClass(name, false);
        } else {
            c = findBootstrapClassOrNull(name);
        }
    } catch (ClassNotFoundException e) {
        // ClassNotFoundException thrown if class not found
        // from the non-null parent class loader
    }

编辑

未经测试,但是类似的事情应该可以完成:

class CustomClassLoader extends URLClassLoader {

    public CustomClassLoader (URL[] urls) throws NoSuchMethodException {
        super(urls);
    }

    @Override
    protected Class<?> loadClass (String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            Class<?> aClass = findClass(name);
            if (resolve) {
                resolveClass(aClass);
            }
            return aClass;
        }
    }
}