GVKun编程网logo

我可以从Java应用程序中删除下载的JNLP文件(Java Web Start / JWS)吗?(如何删除下载的java)

28

本文的目的是介绍我可以从Java应用程序中删除下载的JNLP文件的详细情况,特别关注JavaWebStart/JWS吗?的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了

本文的目的是介绍我可以从Java应用程序中删除下载的JNLP文件的详细情况,特别关注Java Web Start / JWS吗?的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解我可以从Java应用程序中删除下载的JNLP文件的机会,同时也不会遗漏关于Java 7 update 25使我们的Java Web Start应用程序失败且没有日志记录、Java Web Start / JNLP应用程序的jar文件在哪里缓存?、Java Web Start 实践:动态生成 JNLP、Java web start--基于jnlp的软件更新的知识。

本文目录一览:

我可以从Java应用程序中删除下载的JNLP文件(Java Web Start / JWS)吗?(如何删除下载的java)

我可以从Java应用程序中删除下载的JNLP文件(Java Web Start / JWS)吗?(如何删除下载的java)

Google
Chrome浏览器不会自动启动JNLP文件,因此我为我们的用户推荐此解决方案。它可以工作,但是下载的JNLP文件仍保留在下载文件夹中。手动删除它们很麻烦。

我想向我们的Java应用程序添加一个功能:

  1. Google Chrome浏览器下载并打开一个JNLP文件。
  2. JNLP文件启动我们的Java应用程序。
  3. Java应用程序删除JNLP文件(<=我想要此功能!)

我可以获取下载的启动Java应用程序的JNLP文件的文件路径吗?当然,我们的Java应用程序jar已签名并且可以访问本地资源。

Java 7 update 25使我们的Java Web Start应用程序失败且没有日志记录

Java 7 update 25使我们的Java Web Start应用程序失败且没有日志记录

自Oracle启动Java 7 Update 25以来,我们的应用程序不再起作用。

最初,我们收到了一些有关Manifest文件中缺少代码库和安全性标签的警告,我们已对其进行了修复。

我们现在遇到的问题是,在控制台中,我们仅获得以下几行:

#### Java Web Start Error:
#### null

我们还会收到带有错误消息的应用程序错误对话框: 无法启动应用程序

详细信息按钮在例外中提供以下详细信息:

java.lang.NullPointerException
    at com.sun.jnlp.JNLPClassLoader.getPermissions(Unknown Source)
    at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:206)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at desktop.DesktopProxySelector.<init>(DesktopProxySelector.java:24)     <- code smippet below
    at desktop.Main.main(Main.java:139)                                      <- code smippet below
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.sun.javaws.Launcher.executeApplication(Unknown Source)
    at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
    at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
    at com.sun.javaws.Launcher.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:724)

相关代码部分为:

Desktop.Main.main

/**
 * Main method,starts the application
 */
public static void main(String[] args) {
    System.setProperty("java.net.useSystemProxies","true");

    //Logger.getLogger("httpclient.wire.header.level").setLevel(Level.FINEST);
    //Logger.getLogger("org.apache.commons.httpclient.level").setLevel(Level.FINEST);
    java.net.ProxySelector.setDefault(new DesktopProxySelector(java.net.ProxySelector.getDefault()));

(最后一行是行号139)

desktop.DesktopProxySelector:

public class DesktopProxySelector extends ProxySelector {

    public  DesktopProxySelector(ProxySelector defaultSelector) {
    URI httpsUri = new CentralConfigurationService().getCentralLocation();

(最后一行是发生异常的第24行)

有人可以给我们一些线索提示(或更好的解决方案)来说明由此“次要”更新引起的Java新行为。

当我们使用java -jar Desktop.jar从cli直接运行该应用程序时,该应用程序将运行文件,因此该问题显然与Java Web
Start中的更改有关。

@trashgod:该错误显然与7u25中的Permissions更改有关,因为NullPointerException发生在com.sun.jnlp.JNLPClassLoader.getPermissions中。

只是为了解释我的想法(我是Wouter的同事):desktop.Main实例化一个desktop.DesktopProxySelector(我们的类),desktop.DesktopProxySelector实例化desktop.configuration.CentralConfigurationService
desktop.configuration.CentralConfigurationService实例化一个java.net.URI 。

在实例化CentralConfigurationService的DesktopProxySelector初始化的第一行,由JNLPClassLoader调用的getPermissions方法抛出NullPointerException。因此,通过java
webstart加载CentralConfigurationService类并获得该类的权限时出了点问题。可能与URI类实例化(这需要额外的权限(已建立到远程uri的连接))有关吗?

Java Web Start / JNLP应用程序的jar文件在哪里缓存?

Java Web Start / JNLP应用程序的jar文件在哪里缓存?

Java Web Start / JNLP应用程序的jar文件在哪里缓存?

答案1

小编典典

这取决于您的操作系统和虚拟机,例如:

  • 使用Sun JDK 1.5和Windows XP: C:\Documents and Settings\userid\Application Data\Sun\Java\Deployment\cache\javaws\
  • 使用Sun JDK 1.6和Vista: C:\Users\userid\AppData\LocalLow\Sun\Java\Deployment\cache\6.0
  • 使用Sun JDK 1.6和GNU / Linux: /home/userid/.java/deployment/cache/6.0
  • 使用Sun JDK 1.6和Mac OS X: ~/Library/Caches/Java/cache/6.0/

使用Sun JDK 6,可以通过Java控制面板( 常规” 选项卡中的“ Internet临时文件 设置” )进行配置。

Java Web Start 实践:动态生成 JNLP

Java Web Start 实践:动态生成 JNLP

Java 很早就推出了 Java Web Start(简称 JWS)技术。这一技术的初衷很好:希望将桌面程序和 Web 页面之间搭起一个无缝的桥梁。虽然 Applet 技术已经存在了十多年,但是它 日趋老迈衰落,所以 JWS 也就应运而生了。 但是 JWS 并未顺利实现它的初衷。从 Java 的几次大改版都可以看到,JWS 的 bug 多多,漏洞频频,Sun 和 Oracle 不得不频繁的进行打补丁修复。 可以看看 Java 5 和 6 每次大小版本升级变化中,有多少是和 Java Web Start 有关的。难怪很多人都这样感叹:“哥再也不用 Java Web Start 部署应用了!” 其实也未必,随着 Java 的不断完善,我们只要了解更多的技巧,就可以有效的消除一些 JWS 潜在的问题,并顺利的应用在企业应用 中。 以 2BizBox ERP 项目为例,本文介绍如何在企业应用中利用动态生成 JNLP 文件的技术来实现应用的快速部署。

 

大家知道,2BizBox ERP 作为一个免费的高质量 ERP 软件,有成千上万的用户。就我们开发团队负责维护的服务器,就有近千台。每台服务器都是一家企业,每家企业又有几十上百 的客户端。如果采用下载客户端安装程序进行安装的方式来维护诸多的客户端,无疑是巨大的工作量,用户和我们开发团队都不会轻松方便。为了解决这一问题,采 用 JWS 无疑是必然的选择。 

为了让客户端自动启动下载和安装程序,我们在企业的 2BizBox ERP 服务器上部署以下 JNLP 文件内容:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://**.**.**.**/webstart/">
    <information>
        <title>2BizBox</title>
        <vendor>Serva Software</vendor>
        <homepage href="http://www.2bizbox.com" />
        <description>2BizBox ERP 3</description>
        <offline-allowed />
    </information>
    <security>
        <all-permissions />
    </security>
    <update check="always" policy="always" />
    <resources>
        <j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m" />
        <jar href="2bizbox.jar" />
        <jar href=" lib1.jar" />
        <jar href="lib2.jar" />
        <jar href=" lib3.jar" />
        <jar href="lib4.jar" />
        <!-- more jar. -->
    </resources>
    <application-desc main-class=" com.serva.bb2.gui.Main ">
        <argument>**.**.**.**</argument>
    </application-desc>
</jnlp>

上面的 JNLP 文件定义了 2BizBox ERP 客户端启动所需要的 jar 包以及下载位置、jre 版本等。

在实际应用中,效果良好。但是由于 JNLP 和 JWS 本身的 bug,在某些情况下,后台 jar 程序更新升级后,用户侧启动 jnlp 并不能获得更新,需要强行 清空 JWS 缓存才行,这肯定不是一般用户懂得的。还有一种情况,就是由于 ERP 本身的 jar 包发生了变化(例如发生了增减),此时相当于 jnlp 文件的内 容发生了变化。这时候,要求用户一侧机器必须意识到 jnlp 的变化并先将 jnlp 进行更新。在很多 java 版本中(例如 jre6 的早期版本 —— 例如 jre6 update20 之前),由于潜在的一些 bug 等原因,都不能顺利的进行更新,导致程序启动失败。

如何解决这一情况呢?采用动态 jnlp 是一个有效的方法。

动态 jnlp 的思路是:在服务器的后端,通过 jsp 或 servlet 来动态的生成一个 jnlp 文件,而不是放置一个静态的固定不变的 jnlp 文件。这样,jnlp 文件内容就可以通过后台应用的逻辑进行动态生成创建:需要什么 jar 包、需要什么 jre 版本等等。

以 jsp 为例。在这个 jsp 中,首先要注意的几个技术点是:要设置本页面不要被浏览器缓存,放置 jnlp 内容变化无法及时被更新;其次要设置 mime 类型 让浏览器认为它是一个 jnlp 文件,以便下载执行而不是直接在浏览器中显示出来。通过设置 response 即可达到这些目的:

response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
response.setHeader("Content-Disposition", "filename=\"bb.jnlp\";");
response.setContentType("application/x-java-jnlp-file");

其中,禁止浏览器和 webstart 缓存 jnlp 内容,通过设置:response.setHeader ("Pragma", "no-cache"); 和 response.setHeader ("Expires", "0"); 

设置文件类型,并给定一个动态的文件名。这个通过这个进行:response.setHeader ("Content-Disposition", "filename=\"bb.jnlp\";");response.setContentType ("application/x-java-jnlp-file");

一个需要注意的问题是,在动态生成 jnlp 文件时,要注意 jnlp 文件中的 href 标签不要进行设置。为什么呢?看一下 jnlp 的格式文档是这样说的:http://lopica.sourceforge.net/ref.html#jnlp

The jnlp file''s one and only root.

Attributes
spec=version , optional
Specifies what versions of the jnlp spec a jnlp file works with. The default value is 1.0+. Thus, you can typically leave it out.
version=version , optional
Specifies the version of the application as well as the version of the jnlp file itself.
codebase=url , optional
Specifies the codebase for the application. Codebase is also used as base URL for all relative URLs in href attributes.
href=url , optional
Contains the location of the jnlp file as a URL. If you leave out the href attribute, Web Start will disable the update check on your JNLP file, and Web Start will not treat each new JNLP file as an application update - only updated jar files will. Leaving out href usually makes only sense if your jnlp file is created dynamically (that is, throug a cgi-script, for example) and if your jnlp file''s arguments or properties change from request to request (user to user).
Note, that Java Web Start needs href to list your app in the Web Start Application Manager.

可见在动态生成 jnlp 时候就不要设置 href 了,这样就可以保证每次浏览器会重新下载 jnlp 文件内容,否则可能会被缓存,无法及时更新程序。

另外一个技巧是:jnlp 文件中的 jar 包,可以进行动态检查文件 jar 包并动态生成。这样,如果以后程序的 jar 文件有增减,就不必修改 jnlp 文件 了。方法也很简单:检查当前 web 在服务器的绝对路径,并 list 所有的 jar 文件,然后在 jnlp 生成时候输出即可:

<%
	String urlString=request.getRequestURL().toString();
	URL url=new URL(urlString);
	String host=url.getHost();
	String path = request.getSession().getServletContext().getRealPath("/");
	path=path.replace("\\.\\", "\\");
	File file=new File(path);
	String[] files = file.list();
	ArrayList jarNames=new ArrayList();
	for(int i=0;i<files.length;i++){
		String fileName=files[i];
		if(fileName.toLowerCase().endsWith(".jar")){
			jarNames.add(fileName);
		}
	}
%>

然后在 jar 的部分这样列出:

<resources>
	<j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m"/>
	<%
		for(int i=0;i<jarNames.size();i++){
			out.write("\n");
			out.write("<jar href=\""+jarNames.get(i).toString()+"\"/>");
		}
	%>
</resources>

最后,如果需要在 jnlp 中指定当前服务器的 ip 地址或主机地址,也可以通过动态生成。例如 jnlp 文件中的 codebase,就是如此。另 外,2BizBox ERP 还需要在主函数中给出当前服务器的 ip 地址。而对于上千家的 2BizBox 服务器,每个 jnlp 要手工维护 ip 地址,是不可想象的。这里通过动态生 成,就永远的解决了这个问题:

String urlString=request.getRequestURL().toString();
URL url=new URL(urlString);
String host=url.getHost();

然后在 jnlp 中:

<jnlp spec="1.0+" codebase="http://<%=host%>/webstart/">
<application-desc main-class="com.serva.bb2.gui.Main">
	<argument><%=host%></argument>
<application-desc>

这样,通过 jsp 动态生成 jnlp 的方案就完成了。它在 2BizBox ERP 中应用良好,方便的让上千家 2BizBox ERP 的云主机用户快速得到程序更新,而简化了程序的维护方式。

Java web start--基于jnlp的软件更新

Java web start--基于jnlp的软件更新

这几天一直在搞基于jnlp的java程序更新。搞得是晕头转向,手忙脚乱。呵呵,楼主技术比较菜。

还好,马马虎虎算是搞出来了。

其中遇到不少问题,拿出来和大家分享分享,避免以后大家再走弯路。

概念性的东西就不做解释了。

Java web start 百度百科给的很好。

http://baike.baidu.com/link?url=otZSDvcLB1unGU5xMU_Zwzi75Ia-ykut5xIVGb5F0Z1YWp4mSCmFNZcdi4OreWclx8aZ1v1mAfxft9JEG0OjJ_

jnlp 百度百科给的也很好,呵呵。大家可以看下他的定义。

http://baike.baidu.com/link?url=CFeRYNKm2eMu24Lsi5stTfxKbCaV33GCQsq84FNIsqmi0D4aEhDTmk5URi341pHz


楼主理解的Java web start其实就是应用程序部署到浏览器里面,看似是B/S程序,其实是C/S架构(可能理解不对,欢迎指正)。当然Java web start也可以拿出来单独运行。主要就是方面。比传统C/S少了很多安装步骤,比传统B/S多了更好的用户体验,而且可以时刻保存其最新的版本等。

jnlp这个就比较好了。这个东西给楼主的感觉就像是一个快捷方式,这个快捷方式可以指向服务器端的引用。以至于以后如果有软件更新,直接让用户更新一下这个jnlp文件就可以了。jnlp文件非常之小,一般只有几KB。这样的话就大大节省时间,非常提高用户的体验。这样,只需要更新一下服务器端的最新程序,然后让jnlp文件指向这个打好的jar包或者jnlp文件就OK了。

闲话扯了不少。

下面详细说说做这个更新的时候遇到的问题。

1.


这个问题多半就是打包问题。打包签名的安全问题。

写好的项目需要达成jar包和jnlp文件。

楼主打包使用的是ant打包,没有使用现下比较流行的maven。至于为什么,楼主只能说,领导的世界我们不懂。

客户端使用的javafx,需要将客户端打成jar包。类似applet,使用javafx部署这种客户端,因为java的安全策略,java应用程序环境的安全策略,它是由一个Policy对象来表达。

我们需要手动的改一下Java\jre7\lib\security\java.policy文件。我在最后添加了一行permission java.security.AllPermission; 这就是给客户机所有的权限。这样一来,客户端程序就有权限来操作本地的权限。

再有就是需要对客户端程序的jar包进行数字签名。

数字签名:采用加密技术来实现对签名者身份的认证和数据的完整性。简单的说就是你签字的文件别人知道是你签的,并且知 道这个文件是否被修改过。

ant有signjar,使用这个标签给jar包进行签名。java自带的keytool.exe工具也可以实现签名,具体操作请自行查询。

2.

具体错误:

java.lang.ExceptionInInitializerError
    at javax.swing.filechooser.FileSystemView.getFileSystemView(Unknown Source)
    at com.platform.ui.update.DownloadFileController.init(DownloadFileController.java:166)
    at com.platform.ui.update.DownLoadFileView.buildInit(DownLoadFileView.java:41)
    at com.platform.ui.update.MainUpdate.start(MainUpdate.java:17)
    at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:132)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
    at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
    at javax.swing.SwingUtilities.appContextGet(Unknown Source)
    at javax.swing.UIManager.getLAFState(Unknown Source)
    at javax.swing.UIManager.maybeInitialize(Unknown Source)
    at javax.swing.UIManager.getDefaults(Unknown Source)
    at javax.swing.UIManager.getString(Unknown Source)
    at javax.swing.filechooser.WindowsFileSystemView.<clinit>(Unknown Source)
    ... 13 more
Exception in runnable
java.lang.RuntimeException: java.lang.ExceptionInInitializerError
    at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:148)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
    at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
    at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ExceptionInInitializerError
    at javax.swing.filechooser.FileSystemView.getFileSystemView(Unknown Source)
    at com.platform.ui.update.DownloadFileController.init(DownloadFileController.java:166)
    at com.platform.ui.update.DownLoadFileView.buildInit(DownLoadFileView.java:41)
    at com.platform.ui.update.MainUpdate.start(MainUpdate.java:17)
    at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:132)
    ... 8 more
Caused by: java.lang.NullPointerException
    at javax.swing.SwingUtilities.appContextGet(Unknown Source)
    at javax.swing.UIManager.getLAFState(Unknown Source)
    at javax.swing.UIManager.maybeInitialize(Unknown Source)
    at javax.swing.UIManager.getDefaults(Unknown Source)
    at javax.swing.UIManager.getString(Unknown Source)
    at javax.swing.filechooser.WindowsFileSystemView.<clinit>(Unknown Source)
    ... 13 more

这种异常一般都是由于静态变量初始化失败造成,楼主在调用

FileSystemView.getFileSystemView

上面这行代码,调用这个静态方法的时候,程序初始化失败了。这个问题是在测试的时候出现在一个同事的电脑上,于是想到可能不是程序的问题,而是本地电脑环境的问题。于是想到了缓存,如果有缓存存在也可能会导致静态变量初始化失败的情况,清了缓存之后还是不可以,这个问题纠结纳闷了好久。最后发现是jre版本的问题。当时开发的时候都统一了版本,这种情况比较纠结,呵呵。可以肯定的是,版本不一样导致getFileSystemView这个静态方法初始化失败,至于为什么会这样,楼主还在研究当中。

3.

这是在客户那里演示的时候出现的问题,当时比较尴尬了。

看到这个error感觉很致命,程序直接崩了。回来之后测试了N遍也没能重现这个问题,于是远程到客户电脑上看到底怎么回事,也在网上查了。大体都是在说内存不够,导致程序运行不起来。顺便吐槽一下部分程序员,直接就是搬运工,楼主搜了至少10几篇文章都是一个样。。也没标注转载。

于是楼主看了下客户的电脑配置,4G内存,CPU也很空闲。楼主自身电脑也是4G内存,跑这程序刷刷的。又限入无限纠结中,到底怎么回事呢。楼主想到了配置java运行参数的几个地方。比如Xsms,Xsmx之类。先是检查了环境变量的配置。没有问题。然后是jnlp文件的配置(jnlp文件里面有关于java运行内存的配置),也是没问题。最后终于发现问题所在!


在java的控制面板里面,有一项运行时参数,不填写或者填写的大一些,这样就可以运行了。这里限制java的运行环境。


这几个是主要问题,现在回头来看,其实也不是那么难,但在当时真是把楼主折腾的够呛。所谓不识庐山真面目,只缘身在此山中把。楼主深陷其中,一直不得所悟,呵呵。


还有一些显示不了的问题,都是一下小问题。比如把java的安全等级调低。

在调试客户端错误时,有必要将java控制台显示出来,并打印日志等信息。



坦言讲,楼主对于jnlp、javafx以及java web start的理解并不多么深刻,只是最近项目需要,临时研究了下。遇到一些问题和大家分享,希望能够帮助看到的人少走些弯路。如有不对,欢迎指正。QQ:70747053

今天关于我可以从Java应用程序中删除下载的JNLP文件Java Web Start / JWS吗?的讲解已经结束,谢谢您的阅读,如果想了解更多关于Java 7 update 25使我们的Java Web Start应用程序失败且没有日志记录、Java Web Start / JNLP应用程序的jar文件在哪里缓存?、Java Web Start 实践:动态生成 JNLP、Java web start--基于jnlp的软件更新的相关知识,请在本站搜索。

本文标签: