java - 创建仅包含特定文件夹内的类的类加载器

标签 java classloader urlclassloader

我想使用 specific ClassLoaderScriptEngineManager 中加载特定的 jar 文件

This constructor loads the implementations of ScriptEngineFactory visible to the given ClassLoader using the service provider mechanism.

我尝试创建 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)

我还参加了不在类里面的类(class),例如 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)

最佳答案

如 javadoc 中所指定:

public URLClassLoader(URL[] urls)

Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader. The URLs will be searched in the order specified for classes and resources after first searching in the parent class loader. Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be downloaded and opened as needed.

所以你可以尝试扩展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;
        }
    }
}

关于java - 创建仅包含特定文件夹内的类的类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56864832/

相关文章:

Java ClassLoader - 强制重新加载已经加载的类

java - 关于单元测试和日期的首选方法是什么?

Java 正则表达式程序没有按预期工作

java - URLClassLoader 无法在 Linux 上加载依赖项

java - 动态加载类文件抛出ClassNotFoundException

java - 将 Tapestry jar 部署到tomcat lib目录中是错误的吗?

java - 为什么嵌套 Java 循环执行得非常快

java - 方法...必须覆盖父类(super class)方法(最新 SDK)

Java,在类路径中加载 native 库