在运行时将文件添加到 java 类路径

发布于 2024-07-25 01:30:36 字数 105 浏览 5 评论 0原文

是否可以在运行时向 java 类路径添加文件(不一定是 jar 文件)。 具体来说,该文件已经存在于类路径中,我想要的是是否可以将该文件的修改副本添加到类路径中。

谢谢,

Is it possible to add a file (not necessarily a jar file) to java classpath at runtime.
Specifically, the file already is present in the classpath, what I want is whether I can add a modified copy of this file to the classpath.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

撩起发的微风 2024-08-01 01:30:36

您只能将文件夹或 jar 文件添加到类加载器。 因此,如果您有一个类文件,则需要首先将其放入适当的文件夹结构中。

这里是一个相当难看的 hack,它在运行时添加到 SystemClassLoader 中

import java.io.IOException;
import java.io.File;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Method;

public class ClassPathHacker {

  private static final Class[] parameters = new Class[]{URL.class};

  public static void addFile(String s) throws IOException {
    File f = new File(s);
    addFile(f);
  }//end method

  public static void addFile(File f) throws IOException {
    addURL(f.toURL());
  }//end method


  public static void addURL(URL u) throws IOException {

    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class sysclass = URLClassLoader.class;

    try {
      Method method = sysclass.getDeclaredMethod("addURL", parameters);
      method.setAccessible(true);
      method.invoke(sysloader, new Object[]{u});
    } catch (Throwable t) {
      t.printStackTrace();
      throw new IOException("Error, could not add URL to system classloader");
    }//end try catch

   }//end method

}//end class

:访问受保护的方法 addURL 需要反射。 如果存在 SecurityManager,这可能会失败。

You can only add folders or jar files to a class loader. So if you have a single class file, you need to put it into the appropriate folder structure first.

Here is a rather ugly hack that adds to the SystemClassLoader at runtime:

import java.io.IOException;
import java.io.File;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Method;

public class ClassPathHacker {

  private static final Class[] parameters = new Class[]{URL.class};

  public static void addFile(String s) throws IOException {
    File f = new File(s);
    addFile(f);
  }//end method

  public static void addFile(File f) throws IOException {
    addURL(f.toURL());
  }//end method


  public static void addURL(URL u) throws IOException {

    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class sysclass = URLClassLoader.class;

    try {
      Method method = sysclass.getDeclaredMethod("addURL", parameters);
      method.setAccessible(true);
      method.invoke(sysloader, new Object[]{u});
    } catch (Throwable t) {
      t.printStackTrace();
      throw new IOException("Error, could not add URL to system classloader");
    }//end try catch

   }//end method

}//end class

The reflection is necessary to access the protected method addURL. This could fail if there is a SecurityManager.

遮云壑 2024-08-01 01:30:36

试穿这款尺码。

private static void addSoftwareLibrary(File file) throws Exception {
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()});
}

这将编辑系统类加载器以包含给定的库 jar。 它非常丑陋,但它有效。

Try this one on for size.

private static void addSoftwareLibrary(File file) throws Exception {
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()});
}

This edits the system class loader to include the given library jar. It is pretty ugly, but it works.

旧梦荧光笔 2024-08-01 01:30:36

我完成此操作的方法是使用我自己的类加载器

URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
DynamicURLClassLoader dynalLoader = new DynamicURLClassLoader(urlClassLoader);

并创建以下类:

public class DynamicURLClassLoader extends URLClassLoader {

    public DynamicURLClassLoader(URLClassLoader classLoader) {
        super(classLoader.getURLs());
    }

    @Override
    public void addURL(URL url) {
        super.addURL(url);
    }
}

无需任何反射即可工作

The way I have done this is by using my own class loader

URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
DynamicURLClassLoader dynalLoader = new DynamicURLClassLoader(urlClassLoader);

And create the following class:

public class DynamicURLClassLoader extends URLClassLoader {

    public DynamicURLClassLoader(URLClassLoader classLoader) {
        super(classLoader.getURLs());
    }

    @Override
    public void addURL(URL url) {
        super.addURL(url);
    }
}

Works without any reflection

少钕鈤記 2024-08-01 01:30:36

您可以尝试使用 java.net.URLClassloader 以及更新的类所在的文件夹/ja​​r 的 url,并在创建新线程时使用它而不是默认的类加载器。

You coud try java.net.URLClassloader with the url of the folder/jar where your updated class resides and use it instead of the default classloader when creating a new thread.

A君 2024-08-01 01:30:36

是的,我相信这是可能的,但您可能必须实现自己的类加载器。 我从来没有这样做过,但这就是我可能会考虑的道路。

Yes I believe it's possible but you might have to implement your own classloader. I have never done it but that is the path I would probably look at.

蘸点软妹酱 2024-08-01 01:30:36

是的你可以。 如果您想隔离它,它需要位于与其余已编译代码不同的目录中的包结构中。 然后,您只需将其基本目录放在命令行上类路径的前面即可。

yes, you can. it will need to be in its package structure in a separate directory from the rest of your compiled code if you want to isolate it. you will then just put its base dir in the front of the classpath on the command line.

爱已欠费 2024-08-01 01:30:36

我的解决方案:

File jarToAdd = new File("/path/to/file");

new URLClassLoader(((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs()) {
    @Override
    public void addURL(URL url) {
         super.addURL(url);
    }
}.addURL(jarToAdd.toURI().toURL());

My solution:

File jarToAdd = new File("/path/to/file");

new URLClassLoader(((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs()) {
    @Override
    public void addURL(URL url) {
         super.addURL(url);
    }
}.addURL(jarToAdd.toURI().toURL());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文