9

我正在创建一个 URLClassloader 来加载一些罐子。每个 jar 都从不同的类加载器正确加载,每个 jar 都包含一个带有方法 run() 的类。现在这个 run() 的主体可以在其中创建一个匿名内部类。但是,因为我在 try-with-resources 块中创建了我的 URLClassloader,所以它会自动关闭,并且在运行时当它尝试加载匿名内部类时,它会抛出 NoClassDefFoundError,因为类加载器已经关闭。

现在我的问题是,这些情况的正常做法是什么?可以让类加载器保持打开状态,以便以后需要加载其他东西时,它可以吗?有没有办法重新打开一个封闭的类加载器?
如果我让类加载器保持打开状态,编译器会向我发出有关潜在资源泄漏的警告所以我有一种感觉,这就像溪流,你不应该让它们无限期地打开. 但是由于类加载器的性质,如果加载匿名类的不是同一个类加载器,则不能在外部类中使用

这是创建类加载器的代码

public Player(File codePath) throws PlayerException {

   try (URLClassLoader loader = new URLClassLoader(new URL[] { codePath.toURI().toURL() })) {

   //load class from Jar where run() method creates anonymous class that comes in the jar too


   } catch (ClassCastException | IOException | ClassNotFoundException | InstantiationException
| IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException exc) {
throw new PlayerException("Error loading player's code", exc);

}
4

2 回答 2

3

类加载器的生命周期至少应该是加载它的类实例的生命周期。只要他们和他们的类不符合垃圾回收的条件,他们的类加载器也不是。如果他们需要加载额外的代码或资源,您需要打开类加载器。

因此,当您完成播放器时,您应该关闭类加载器。

于 2012-12-19T08:50:45.927 回答
0

您可以使用工厂模式(或类似的东西),而不是为每个玩家创建一个新的类加载器:

URLClassLoader loader = PlayerClassLoaderFactory.getInstance().getClassLoader(codePath.toURI())

工厂维护对类加载器的引用(因此这些类不是孤立的)。然后,如果需要关闭类加载器,您就可以“关闭”工厂。

于 2012-12-19T06:36:27.320 回答