是否可以在 JWS 中加载 jars-in-jars?

发布于 2024-09-28 18:01:44 字数 2510 浏览 4 评论 0原文

我发现许多线程将所有依赖项与项目一起打包到一个 jar 包中,并且似乎有许多不同的方法可以实现这一目标(oneJar、FatJar、Ant-build...)

所以烹饪我自己的食谱,我(经过相当多的努力)设法打包了我正在从事的项目。在这个 jar 文件中,有该项目的代码以及该项目所依赖的所有 jar,这些 jar 是通过 eclipse 附带的 jar-in-jar-loader 加载的。当结果通过 java -jar myjarfile 调用的终端运行时,它可以在许多不同的平台上正常运行。

你可能会说,Peachy,但这就是问题所在;当我签署我的 jar 并尝试通过 javaws 运行它(这是这里的最终目标)时,我得到一个异常,我已解密该异常意味着 库(在 org.apache.commons.lang.SystemUtils 下面的情况下)无法访问。

这是我的问题;当为 Java Web Start 部署应用程序时,是否无法加载 jars 中的 jars? 如果可以,我做错了什么?如果没有,最好的选择是什么?

谢谢!


下面是 JNLP 文件以及运行 javaws myJNLPfile 时得到的 stackTrace

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="file:///home/ukirik/workspace/myproject/dist"
href="project.jnlp">

<information>
    <!-- Project info -->
</information>
<security>
    <all-permissions />
</security>
<resources os="Mac\ OS\ X">
    <j2se version="1.6+" java-vm-args="-XstartOnFirstThread"/>
</resources>
<resources>
    <jar href="myjar-jws.jar" />
</resources>
<application-desc main-class="org.gvt.RuntimeMain"/>            
</jnlp>

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1799)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1745)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1507)
at com.sun.javaws.Launcher.run(Launcher.java:129)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/lang/SystemUtils
at org.gvt.RuntimeMain.loadSwtJar(RuntimeMain.java:27)
at org.gvt.RuntimeMain.main(RuntimeMain.java:13)
... 9 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.SystemUtils
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at com.sun.jnlp.JNLPClassLoader.findClass(JNLPClassLoader.java:332)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 11 more

I have found MANY threads on packing all dependencies along with the project into one jar package, and it seems like there are many different ways to achieve this (oneJar, FatJar, Ant-build...)

So cooking up my own recipe, I have (after quite some effort) managed to package the project I am working on. In this one jar file, there is the code for the project plus all the jars that the project depends on which are loaded with jar-in-jar-loader that comes with eclipse. The resultant works fine on a number of different platforms, when it's ran through the terminal invoked via java -jar myjarfile.

Peachy, you might say, here's the problem though; when I sign my jar and try to run it via javaws (which is the ultimate goal here) I get an exception which I have decrypted to mean that libraries (in the case below org.apache.commons.lang.SystemUtils) are unaccessible.

So here's my question; is it not possible to load jars in jars when the applications is deployed for Java Web Start? If it is possible, what am I doing wrong? If not, what's the best alternative?

Thanks!


Below is the JNLP file along with the stackTrace I get when I run javaws myJNLPfile

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="file:///home/ukirik/workspace/myproject/dist"
href="project.jnlp">

<information>
    <!-- Project info -->
</information>
<security>
    <all-permissions />
</security>
<resources os="Mac\ OS\ X">
    <j2se version="1.6+" java-vm-args="-XstartOnFirstThread"/>
</resources>
<resources>
    <jar href="myjar-jws.jar" />
</resources>
<application-desc main-class="org.gvt.RuntimeMain"/>            
</jnlp>

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1799)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1745)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1507)
at com.sun.javaws.Launcher.run(Launcher.java:129)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/lang/SystemUtils
at org.gvt.RuntimeMain.loadSwtJar(RuntimeMain.java:27)
at org.gvt.RuntimeMain.main(RuntimeMain.java:13)
... 9 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.SystemUtils
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at com.sun.jnlp.JNLPClassLoader.findClass(JNLPClassLoader.java:332)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 11 more

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

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

发布评论

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

评论(3

说好的呢 2024-10-05 18:01:44

如果您使用 Eclipse jar-in-jar 加载器,我认为您可能需要在 jnlp 文件中使用它,

<application-desc main-class="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>

假设您的清单如下所示...

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 20.1-b02 (Sun Microsystems Inc.)
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Rsrc-Main-Class: yourapp.mainclass
Rsrc-Class-Path: ./ swt.jar velocity-1.7-dep.jar
Class-Path: .

If you are using the Eclipse jar-in-jar loader I think that you may need this in the jnlp file

<application-desc main-class="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>

That's assuming that your manifest is looking like this...

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 20.1-b02 (Sun Microsystems Inc.)
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Rsrc-Main-Class: yourapp.mainclass
Rsrc-Class-Path: ./ swt.jar velocity-1.7-dep.jar
Class-Path: .
左耳近心 2024-10-05 18:01:44

看来问题出在类加载器上。

您可能希望在 JWS 中使用自定义类加载器,如下所述:

http://lopica.sourceforge。 net/faq.html#customcl

根据您需要执行的具体操作,在打包方面,有几个选项。

It seems like the problem is with the classloader.

You may want to use a custom classloader in JWS, as described here:

http://lopica.sourceforge.net/faq.html#customcl

Depending on exactly what you need to do, in terms of packaging, there are a couple of options.

嗳卜坏 2024-10-05 18:01:44

您遇到的问题是,您将 org.gvt.RuntimeMain 作为 JNPL 文件中 jar 的主类传递,但这是一个单 jar jar。因为它是一个 one-jar jar,所以您需要提供类 com.simontuffs.onejar.Boot,因为

<application-desc main-class="com.simontuffs.onejar.Boot"/>  

它的原因是 one-jar 插件将生成该类,它将利用一个理解 jar 的类加载器在 jar 中,然后调用 org.gvt.RuntimeMain 类(它通过查看清单的 One-Jar-Main-Class: 标头来计算出来)。

The problem you're running into is that you're passing org.gvt.RuntimeMain as your main class for your jar in your JNPL file, but that's a one-jar jar. Because it's a one-jar jar, you need to provide class com.simontuffs.onejar.Boot instead, as

<application-desc main-class="com.simontuffs.onejar.Boot"/>  

The reason for it, is that the one-jar plugin will generate that class, which will make use of a classloader that understands jars within jars, and then invoke your org.gvt.RuntimeMain class (it figures it out through looking at the manifests's One-Jar-Main-Class: header).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文