如何在 jar 文件上远程执行方法

Posted

技术标签:

【中文标题】如何在 jar 文件上远程执行方法【英文标题】:How to execute a method remotely on a jar file 【发布时间】:2011-05-23 16:49:07 【问题描述】:

我有一个应用程序,其目的是在跨文件系统的许多不同 jar 文件中调用同一类中的相同特定方法并接收结果。所以我可以保证某个类和方法会存在于一个jar文件中。

我知道每个 jar 文件的位置。我很容易通过反射来实例化类并以这种方式调用方法。

我的问题是我有很多这些 jar 文件。如果我使用上述方法调用每个 jar,我担心我的应用程序的内存消耗会急剧增加,因为我必须为每次调用加载整个 jar 文件。

除了反射之外,我还有什么方法可以调用这些 jars 文件?系统调用不起作用,因为我需要接收一个值。

非常感谢...

【问题讨论】:

出于兴趣,如何在代码中从不同的 jar 文件中加载同一个类? 您是否考虑过使用单独的类加载器并在最后处理它?我认为这就是容器进行 .jar 管理 (Tomcat) 的方式。 @DaveHowes - 我只是创建了一个本地 URLClassloader,其中包含我感兴趣的 jar 文件的 URL。然后我使用 Class.ForName() 等。 @Rekin - 是的,我使用本地 URLClassloader,它在调用完成后超出范围。然而此时,我感兴趣的 jar 已经加载完毕。它还会留在记忆中吗? @Belltower: AFAIK 类定义直接进入 perm gen 空间,这很少被扫除,但有时仍然如此。当没有任何东西引用它们时,就没有理由保留它们。也许 Jochen 可以纠正我。 【参考方案1】:

您可能会遇到烫发空间的问题,但可以使用-XX:MaxPermSize= 增加此问题 参数。

确保您为每个 JAR 文件使用单独的 URLClassLoader,并且不要保留它们以便获取 GCd。 通过新的 URLClassLoader 加载 JAR 文件,然后使用 Class.forName() 加载。

祝你好运!

【讨论】:

是的,这就是我目前的做法。我创建了一个本地 URLClassLoader,其中包含我感兴趣的 jar 文件的路径。然后我使用 class.FoName() 等。不过,一旦通过 ClassLoader 加载 jar 文件,它是否会保留在内存中? ClassLoader 已经被 GC 处理了吗? 曾经有关于打开文件和 URLClassLoaders 的问题。如果您有幸使用早期的 Java 7 版本,它在 URLClassLoaders 上有一个新的 close() 方法。 你还要考虑JVM中的缓存机制。我想没有办法在 URLClassLoader 缓存中禁用缓存。【参考方案2】:

我会做这样的伪代码:

foreach jf : myJarFiles
  jcl = new JarClassLoader(jf);
  Class.forName(myClassName);
  m = MyClass.getMethod(...);
  m.invoke(...);

【讨论】:

是的,我就是这样做的。它只是我担心的罐子管理方面。一旦本地类加载器超出范围,我希望将已加载到内存中的 jar 文件释放。否则我担心重复调用加载 jar 文件后的内存大小。 @belltower:请注意,JVM 的内存使用量会随着您加载每个 JAR 文件而增加,但只要您为每个 JAR 文件使用单独的类加载器,那么垃圾收集器就会释放内存 需要时,假设您不保留不需要的引用。 那是完美的。感谢您的宝贵时间!

以上是关于如何在 jar 文件上远程执行方法的主要内容,如果未能解决你的问题,请参考以下文章

如何让Jenkins在远程服务器上执行删除操作

WMI如何远程执行命令?

如何从远程执行的 Fargate 任务访问 S3 对象?

命令行登录FTP下,如何远程执行服务器上的可执行文件?不是在本机执行,而是远程执行,命令是啥呢。求高

linux远程运行jar包 关闭窗口后程序就停了,怎么解决

如何从 .sh 可执行文件执行远程 Python 文件?