Java:如何从本机安装程序创建可工作的.exe?

Java:如何从本机安装程序创建可工作的.exe?,java,netbeans,installation,exe,Java,Netbeans,Installation,Exe,我有一个程序,我希望能够被任何用户轻松安装,我认为创建一个本机安装程序是一个不错的选择。我使用了Netbeans 8.0的功能(项目属性>启用本机打包和打包为)。我能够创建一个正常工作的本机安装程序。安装后,我有以下文件树: +-- Project \+-- app \+--lib (containing all the jars used by the project) \---Project.jar \---package.cfg

我有一个程序,我希望能够被任何用户轻松安装,我认为创建一个本机安装程序是一个不错的选择。我使用了Netbeans 8.0的功能(项目属性>启用本机打包和打包为)。我能够创建一个正常工作的本机安装程序。安装后,我有以下文件树:

+-- Project
    \+-- app
         \+--lib (containing all the jars used by the project)
         \---Project.jar
         \---package.cfg
    \+--runtime
        \+--jre (contains the current jre)
    \---Project.exe
从Project.jar执行程序是可行的。但是,当我尝试启动Project.exe时,在弹出的窗口中出现以下错误消息,其中没有任何详细信息:

由于主类异常而失败

为了找出问题的根源,我使用了基本的标准输出,并借助Windows命令提示符将它们重定向到一个文件中。在第一次调用外部库之前,我一直得到输出。因此,库链接似乎没有完成。但是,下面是我的
package.cfg
文件的内容:

app.mainjar=Project.jar
app.mainclass=project/Main
app.classpath=lib/firstlibrary.jar lib/secondlibrary.jar 
已指定类路径,但似乎无法识别。我曾尝试反转斜杠(\)并更改
的空格无效

有一种简单的方法可以重现该错误(Netbeans 8.0和JDK 1.8u11):

  • 在Netbeans中创建新的Java项目
  • 链接任何外部库(.jar):右键单击库>添加jar/文件夹
  • 在main方法中,实例化引用该库的对象
  • 右键单击项目菜单中的项目名称>属性>部署>启用本机打包操作
  • 右键单击项目>软件包as>EXE安装程序
  • 生成后,转到已创建安装程序的目录,并启动安装程序
  • 在安装结束时,转到安装目录,并启动.exe。错误应该发生

知道如何解决这个问题吗?

我认为您的主类未正确设置为包。 不使用Netbeans,您可以使用exe4J从jar文件生成exe。(请确保从project>properties>run>main类设置了main类


下载exe4J我刚刚遇到了一个与本机打包的JavaFX应用程序类似的问题,在该应用程序中,我遇到了“由于主类异常而失败”错误。我的package.cfg看起来与您的相同

我所做的诊断只是从命令行手动运行jar文件(例如Project.jar)并查看stacktrace是什么,例如,如果您的主类位于org.Project.Project中

java -cp Project.jar org.project.Project

对我来说,我用来加载打包在jar中的各种文件(例如,JavaFX的FXML文件)的URL导致了问题——我使用的是相对URL(例如“/blah.ext”或“./foo.txt”等),但一旦我根据文件在jar中的布局将URL更改为绝对URL,它就可以正常工作(例如。“/org/project/blah.ext”和“/org/foo.txt”)。

同样的问题,使用这些:

  • Java SE版本8更新31(build 1.8.0_31-b13)
  • NetBeans 8.0.2(修补程序1)
  • 英特尔Core i7(64位)上的Windows 7企业版SP1
  • Inno安装编译器5.5.5(u)-Unicode
我还通过重定向printlns来跟踪输出,当它第一次调用外部库时它就崩溃了。我想我可能和matt1有同样的问题,所以我修复了所有的相关路径,但没有任何乐趣。我最终发现安装程序没有用外部jar文件创建/app/lib文件夹。在手动复制lib fo之后它工作正常,即使在没有安装JRE的机器上(我正在开发一个独立的应用程序)

修复方法是在build.xml中添加一行:

   <target name="-post-jfx-deploy">
   <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" 
             nativeBundles="all"
             outdir="${basedir}/${dist.dir}" outfile="${application.title}">
      <fx:application name="${application.title}" mainClass="${javafx.main.class}"/>
      <fx:resources>
          <fx:fileset dir="${basedir}/${dist.dir}" includes="*.jar"/>
          <!--below is the magic bit that copies all the dependency jar files to the native package output-->
          <fx:fileset dir="${basedir}/${dist.dir}" includes="lib/*.jar"/>
      </fx:resources>
      <fx:info title="MyApp" vendor="MyVendor"/>
  </fx:deploy>          
</target>


第二个fileset指令强制从lib文件夹中复制jar依赖项,这修复了作为EXE或MSI部署时的所有问题。

您可以为库链接提供完整的输出吗?输出对应于对System.out.println()的调用。由于没有关于错误消息的详细信息,我不得不进行调试。显然,当您启动exe时,它不会在任何地方打印消息。因此,我使用
操作符重定向了文件中的stdout,并获得打印消息,直到使用外部库的对象被实例化。有人能确认此错误发生在他们的计算机上吗?您好@Koln,您能解释一下您是如何做到这一点的吗“为了确定问题的根源,我使用了基本的标准输出,并通过Windows命令提示符将它们重定向到一个文件中“。我在命令行中没有看到任何内容,我希望跟踪类似的problem@ZiglioNZ在前面的评论中已经解释过了,我添加了大量的
System.out.println()
在我知道bug很有可能发生的地方,通过终端启动了我的exe并重定向了输出。类似于
file.exe>mystacktrace.txt
hi@TxF,你能解释一下你是如何做到的吗“我还通过重定向printlns'来跟踪输出?谢谢!我明白了,只需要使用redirection>从命令行调用,它只输出到一个文件,这有点不方便。此外,我看不到任何异常堆栈跟踪,也许我需要重定向stderr。是的,但总比什么都没有好。:)您可以随时执行以下操作:“e.printStackTrace();“在一个catch块内,该块将输出推送到standard out,这应该会在重定向文件中结束(如果需要,您可以强制执行错误条件)。谢谢,我发现了如何打印异常堆栈跟踪:>executable/Debug