相关疑难解决方法(0)

在java中卸载类?

我有一个自定义类加载器,以便桌面应用程序可以动态地从我需要与之交谈的AppServer加载类.我们之所以这样做是因为要做这件事所需的罐子数量是荒谬的(如果我们想要运送它们).如果我们不在运行时从AppServer库动态加载类,我们也会遇到版本问题.

现在,我遇到了一个问题,我需要与两个不同的AppServer交谈,并发现根据我首先加载的类我可能会破坏...有没有办法强制卸载类而不实际杀死JVM?

希望这是有道理的

java classloader

170
推荐指数
5
解决办法
13万
查看次数

Scala中的"eval"

Scala可以用来编写Java应用程序的脚本吗?

我需要从Java加载一段Scala代码,为它设置执行范围(主机应用程序公开的数据),评估它并从中检索结果对象.

Scala文档显示了从Java调用编译的Scala代码是多么容易(因为它变成了常规的JVM字节码).

但是我如何动态评估Scala表达式(从Java或者如果在Scala中更容易)?

对于许多其他语言,有javax.scripting接口.Scala似乎不支持它,我在Java/Scala互操作性文档中找不到任何不依赖于提前编译的东西.

java scripting scala embedding

56
推荐指数
5
解决办法
2万
查看次数

如何在Java中卸载已加载的类?

如何从类加载器中卸载一个类,以便我可以动态使用最近更改的类而无需重新启动我的应用程序(热部署)?有可能吗?

java classloader

15
推荐指数
2
解决办法
2万
查看次数

卸载类加载器

我的最终目标是能够在已经加载到JVM之后重新加载类.

阅读下面的答案后在java中卸载类?,我一直在尝试实现自己的Class-Loader,它本身为它加载的每个类创建一个不同的Class-Loader实例(它自己的类型).

所以,结果是每个Class-Loader一个类.

目的是能够GC类,意味着它的所有实例,然后卸载它的类加载器,并能够从其字节重新加载相同的类.

问题是 - 我可以看到我的类实例使用finalize()方法进行垃圾收集,但是我不能让我的类加载器卸载,或者被垃圾收集.
是否有任何代码示例,一个简单的测试,显示它是如何完成的?

谢谢,任何帮助将不胜感激

编辑:

更清楚的是,我对代码示例感兴趣,其中新对象的实例化是通过'new()'操作数,而类加载器没有显式重新加载主要的类,但是在下一个'new(之后) )' 叫做.

java garbage-collection classloader

7
推荐指数
1
解决办法
6303
查看次数

在运行时将 Scala 3 代码从字符串解析为 Scala 3 AST

我的目标是将 Scala 3 代码作为字符串获取,并在运行时将其解析为 Scala 3 的抽象语法树。在这个过程中,如果代码有编译错误,我应该把它作为一些异常的一部分。更大的目标是,如果 Scala 代码有效,则以 Expr[T] 结束,并通过拼接正确的位来执行它(我已经介绍了这部分)。

这在 Scala 2.* 中是可行的,在这里使用 scala-reflect 。

val source =
  """
    |object HelloWorld {
    |  def main(args: Array[String]): Unit = {
    |    println("Hello, world!")
    |  }
    |}
    |
    |HelloWorld.main(Array())
    |""".stripMargin
val tree = toolbox.parse(source)
val binary = toolbox.compile(tree)
binary()
Run Code Online (Sandbox Code Playgroud)

但据我推测,在 Scala 3 中,不会移植 scala-reflect。我如何在 Scala 3 中实现相同的目标?

这里和这里的一些相关链接

reflection scala scala-3

7
推荐指数
1
解决办法
136
查看次数

当这些类可能正在使用时,如何成功卸载这些类?

我在我的应用程序中内置了重新加载类的功能。但是,我需要澄清类加载器的行为。

让我解释一下我所知道的,然后提出问题......

我所做的是提供一个由自定义类加载器加载的特殊 jar。然后在 jar 的引导过程中,创建了一堆 spring bean,并且实现某些接口的 bean 被注册以供中央应用程序使用。

现在我在应用程序中启动一个使用这些新类的进程。我可以成功卸载“jar”,更改 jar 中的类并重新加载,然后我就得到了更改。用类加载器的说法来说,卸载意味着使加载类的类加载器无法访问 - 这会导致该类加载器加载的任何类都无法访问,从而有效地卸载。

但是,据我所知,一旦虚拟机加载了该类,它就会将其存储在某个共享空间中,因此不必再次加载它。

我遇到的问题是,有时卸载和重新加载新类不起作用。旧班级仍然存在。按理说,如果我卸载一个类加载器(即使类加载器无法访问)并且该类加载器中的某个类当前正在使用(存在该类型的对象),则无法卸载该类。

这是真的?实践中似乎也是如此。

如果是这样,我如何成功卸载类加载器无法访问时正在使用的类。例如,我可以在每个类上放置一个弱引用,以便我可以检测到类何时无法访问,并在类无法访问时采取行动吗?(但不确定我可以采取什么行动)。

更新响应@Kayaman

我的用例是,我拥有核心应用程序,然后根据客户的要求,我可以加载实现核心应用程序中已知接口的不同类(以便可以访问它们)。然后核心应用程序启动使用这些类的各种进程。这样做的一大优点是,我可以更新这些插件类,而无需进行大量的重新部署,并且每个客户并不需要其中的每一个。当我想加载其中之一的新版本并且当前版本正在使用时,问题就出现了。按理说这是不可能的。

结论

@Kayamam 非常感谢您的咨询。这非常有帮助。这在一定程度上规范了我的想法。结论是,无论我使用什么技术,在虚拟机的现有方式下,您都无法重新加载当前存在强可达对象的类。对于我的一些重新加载,我可以控制这些对象,因为我可以在卸载和重新加载之前使它们无法访问,但对于其他类,我不能这样做......这就是我的问题所在。我需要做的是围住我希望重新加载的类的对象,以便在重新加载这些对象的类时可以暂停使用它们的进程。

java classloader dynamic-class-loaders

2
推荐指数
1
解决办法
5863
查看次数