2014-07-13 26 views
2

我還在學習JavaFX的細節。一個主要的區別是在dist文件夾(除了庫)之外,我發現除了.jar文件外,還有一個HTML文件和一個JNLP文件,既沒有對我有用(這將是桌面應用程序)。如何將JavaFX應用程序簽名並部署到單個.JAR中?

我發現了以下(因爲敏感/無關信息省略屬性):

<delete dir="${store.dir}"/> 
<mkdir dir="${store.dir}"/> 

<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip"> 
    <zipgroupfileset dir="dist" includes="*.jar"/> 
    <zipgroupfileset dir="dist/lib" includes="*.jar"/> 

    <manifest> 
     <attribute name="Main-Class" value="${main.class}"/> 
    </manifest> 
</jar> 

<zip destfile="${store.jar}"> 
    <zipfileset src="${store.dir}/temp_final.jar" 
    excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/> 
</zip> 
    <delete file="${store.dir}/temp_final.jar"/> 

    <delete  dir = "${build.output.dir}"/> 
    <mkdir  dir = "${build.output.dir}"/> 

    <signjar 
       jar = "${store.jar}" 
      signedjar = "${build.output.dir}/${FileName}" 
       alias = "${comodo.key.alias}" 
      storepass = "${comodo.key.storepass}" 
      keystore = "${comodo.key.store}" 
      storetype = "PKCS12" 
      keypass = "${comodo.key.pass}" 
      tsaurl = "${timestamp.url}"/> 

這是爲了建立兩個「可執行」 MAIN JAR和所有相關的庫成一個單一的。 JAR可以從任何位置運行,然後拿起並簽名該JAR並將其移動到「簽名」目錄中。

這對於任何JAR庫或Swing GUI應用程序的JAR工作正常,但是當我試圖用JavaFX應用程序一樣的東西它borked:

Error: Could not find or load main class com.javafx.main.Main 

我不完全驚訝地發現它不能正常工作,但它有點問題。我做了一些關於可能部署「獨立」應用程序的研究,但這不符合我們的需求。我的僱主在某種程度上採購了Comodo證書,並且我很快遇到了一堵牆,看起來由於Apple的詭計(除非我錯誤地認爲這種推定),您必須加入他們的開發者俱樂部,以$ 100 a的低廉價格一年(沒有發生)。我並不真正爲蘋果平臺開發。我在做Java開發。無論如何,如果我是正確的,將不適合我們這樣一個獨立的Windows,Linux和Mac的部署出來(再次,如果我是正確的)。

我希望這是簡單的事情。

那麼,如何將我創建的ANT腳本應用於將包含所有相關LIB的JAR編譯爲帶有代碼簽名JAR的JavaFX應用程序?

編輯1:好吧,所以肯定說得太快。不是非常接近答案。我試圖frankenstein關於編譯和簽名常規JAR文件的知識,以便所有庫都包含在內,並且該符號能夠成功從我已經能夠從manual中挑選出來。我擁有的是大雜燴和失敗。除了主要的.JAR文件外,我還得到一個包含所有內容的.JAR文件。反正這是Ant腳本代碼:

屬性:

<property name = "name" 
      value = "APPNAME"/> 

<property name = "file" 
      value = "APPJAR"/> 

<property name = "MC" 
      value = "MAINPACKAGE.MAINCLASS" /> 

<property name = "released.dir" 
      value = "released"/> 

<property name = "compiled.dir" 
      value = "${released.dir}/compiled"/> 

<property name = "stored.dir" 
      value = "${released.dir}/stored"/> 

<property name = "signed.dir" 
      value = "${released.dir}/signed"/> 

其他的一切:

<delete dir = "${released.dir}"/> 
     <mkdir dir = "${compiled.dir}"/> 

     <fx:jar destfile = "dist/compiled.jar"> 
      <fx:platform javafx = "8.0+" j2se = "8.0"/> 
      <fx:application  name = "${name}" 
          mainClass = "${MC}"/> 

      <fileset dir = "build/classes"/> 

      <fx:resources> 
       <fx:fileset dir = "dist" includes = "lib/*.jar"/> 
      </fx:resources> 
     </fx:jar> 

     <fx:signjar keystore = "${comodo.key.store}" 
         alias = "${comodo.key.alias}" 
        storetype = "PKCS12" 
        keypass = "${comodo.key.pass}" 
        storepass = "${comodo.key.storepass}" 
         jar = "dist/compiled.jar" 
        destdir = "${compiled.dir}"/> 

     <mkdir dir = "${stored.dir}"/> 

     <jar  destFile = "${stored.dir}/temp_final.jar" 
      filesetmanifest = "skip" > 
      <zipgroupfileset  dir = "${compiled.dir}" 
          includes = "compiled.jar"/> 

      <zipgroupfileset  dir = "dist/lib" 
          includes = "*.jar"/> 

      <manifest> 
       <attribute name = "Main-Class" 
          value = "${main.class}"/> 
      </manifest> 
     </jar> 

     <zip destfile = "${stored.dir}/${file}"> 
      <zipfileset src = "${stored.dir}/temp_final.jar" 
        excludes = "META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/> 
     </zip> 

     <delete file="${stored.dir}/temp_final.jar"/> 

     <mkdir dir = "${signed.dir}"/> 

     <signjar 
      keystore = "${comodo.key.store}" 
       alias = "${comodo.key.alias}" 
      storetype = "PKCS12" 
       tsaurl = "${timestamp.url}" 
      keypass = "${comodo.key.pass}" 
      storepass = "${comodo.key.storepass}" 
       jar = "${stored.dir}/${file}" 
      destdir = "${signed.dir}"/> 

而這正是我要顯示我的時間。如果任何人都能從中獲得一些可能讓我走上正軌的東西(如果我離得很近,我不覺得自己就是這樣),那就太棒了。

+0

可能已經找到了一個諮詢文檔的答案。不要認爲這會很容易... – Will

回答

0

在將我的頭骨及其中的內容猛擊成泥漿之前,我已經設法完成了我已經完成的任務。其中大部分來自其他人的貢獻以及諮詢docs。另一個主要貢獻是發現here(線程的最後一條評論,它鏈接到另一個SO答案,但這樣的答案對我來說幫助不大)。感謝所有能夠提取解決方案部分的內容。我希望這對所有需要/希望完成此任務的人都有幫助。

總之:首先第一件事情:屬性:

<property name = "JFXProject.name" 
     value = "PROJECT"/> <!-- Put your own project name here --> 
<property name = "JFXMainClass" 
     value = "MAINPACKAGE.MAINCLASS"/> <!--Put your own main class here --> 
    <!-- don't edit below this line --> 
<property name = "JFX.src.dir" 
     value = "src"/> 
<property name = "JFX.lib.dir" 
     value = "dist/lib"/> 
<property name = "JFX.build.dir" 
     value = "release/JFXBuild"/> 
<property name = "JFX.sign.dir" 
     value = "release/JFXSign"/> 
<property name = "store.dir" 
     value = "release/store"/> 
<property name = "sign.dir" 
     value = "release/sign"/> 
<property name = "comodo.key.store" 
     value = "PATH-TO-YOUR-CERTIFICATE" /> <!-- You can name this what you like, but you want to make sure the value points to your certificate or JKS file --> 

<property name = "comodo.key.storepass" 
     value = "PASSWORD"/> <!-- Above applies here. Make sure it's the right password --> 

<property name = "comodo.key.alias" 
     value = "ALIAS"/> <!-- Make sure it's your right alias. You can find out how to find that information from [here][3] --> 

<property name = "comodo.key.pass" 
     value = "PASSWORD"/> <!-- In my own experience this was the same as the storepass but it may be different for you --> 

<property name = "timestamp.url" 
     value = "TIMESTAMPURL"/> <!-- This will vary for you depending on your certificate. --> 

您可以更改屬性名稱的東西,如果你想要更多的對你有意義的,但要確保它們在整個腳本一致。

接下來,我們要清理掉最後的構建:

<target name = "JFXClean"> 
    <echo>Cleaning ${JFX.build.dir}...</echo> 
    <delete dir = "${JFX.build.dir}"/> 
    <delete dir = "${JFX.sign.dir}"/> 
    <delete dir = "${store.dir}"/> 
    <delete dir = "${sign.dir}"/> 
</target> 

然後,我們要爲一個新的乾淨的構建重新創建目錄...

<target name = "JFXInit" depends = "JFXClean"> 
    <echo>Creating the build directory...</echo> 
    <mkdir dir = "${JFX.build.dir}"/> 
    <mkdir dir = "${JFX.sign.dir}"/> 
    <mkdir dir = "${store.dir}"/> 
    <mkdir dir = "${sign.dir}"/> 
</target> 

這部分是關鍵以獲得可運行的JavaFX JAR文件:

<target name = "JFXBuild" depends = "jar, JFXInit"> 
    <fx:jar destfile = "${JFX.build.dir}/${JFXProject.name}.jar"> 
     <fx:application name = "${JFXProject.name}" 
        mainClass = "${JFXMainClass}"/> 
     <fileset dir = "build/classes"/> 
    </fx:jar> 
</target> 

這會將所有部件正確存儲到它們在JAR(包括您可能擁有的任何CSS和JFXML文件。如果您沒有創建JFXML應用程序,則可能不需要。我不知道我沒有測試過它。

然後,我們要簽署的JavaFX的JAR:

<target name = "JFXSign" depends = "JFXBuild"> 
    <fx:signjar keystore = "${comodo.key.store}" 
        alias = "${comodo.key.alias}" 
       storetype = "PKCS12" <!-- This is necessary for me, but may not be for you if you are not using a PFX file --> 
        keypass = "${comodo.key.pass}" 
       storepass = "${comodo.key.storepass}" 
         jar = "${JFX.build.dir}/${JFXProject.name}.jar" 
        destdir = "${JFX.sign.dir}"/> 
</target> 

之後還有2個目標,即把手採購拉鍊,然後設置該郵政編碼,以及一個決賽演唱的最後一罈子:

<target name = "build" depends = "JFXSign"> 
    <jar destfile = "${store.dir}/temp_final.jar" 
    filesetmanifest = "skip"> 
     <zipgroupfileset dir = "${JFX.build.dir}" 
        includes = "*.jar"/> 
     <zipgroupfileset dir = "${JFX.lib.dir}" 
        includes = "*.jar"/> 
     <manifest> 
      <attribute name = "Main-Class" 
         value = "${JFXMainClass}"/> 
     </manifest> 
    </jar> 
</target> 

<target name = "store" depends = "build"> 
    <zip destfile = "${store.dir}/${JFXProject.name}.jar"> 
     <zipfileset src = "${store.dir}/temp_final.jar" 
       excludes = "META-INF/*sf, META-INF/*.DSA, META-INF/*RSA"/> 
    </zip> 
    <delete file = "${store.dir}/temp_final.jar"/> 
</target> 

<target name = "BuildStoreAndSign" depends = "store"> 
    <signjar 
     keystore = "${comodo.key.store}" 
      alias = "${comodo.key.alias}" 
     storetype = "PKCS12" <!-- This is necessary for me, but may not be for you if you are not using a PFX file --> 
      tsaurl = "${timestamp.url}" 
      keypass = "${comodo.key.pass}" 
     storepass = "${comodo.key.storepass}" 
       jar = "${store.dir}/${JFXProject.name}.jar" 
      destdir = "${sign.dir}"/> 
    <delete dir = "${JFX.compile.dir}"/> 
    <delete dir = "${JFX.build.dir}"/> 
    <delete dir = "${JFX.sign.dir}"/> 
    <delete dir = "${store.dir}"/> 
</target> 

我無法真正解釋很多這方面的問題,因爲我遠遠沒有接近這方面的專家。我基本上可以從示例代碼和源代碼中找到我正在查看的內容,並將它們放在一起得到: 最後一點半幫助的信息是this,但請注意這一點不要使用one-jar(我用一個jar文件試過,但它不起作用,它沒有引入CSS或應用它)。

此外,有點警告:This worked for me。我無法保證它會適合你,但我想象一下,它會產生類似於我的結果(一個運行在你放置它的地方的單個.JAR JavaFX應用程序)。

+0

期待您的回答@威爾。考慮在你的答案下將它改爲評論,然後在你弄明白的時候發佈你的完整答案。 – aliteralmind

+1

對不起,但好消息是我有一個工作解決方案! – Will

0

甲骨文說:http://www.oracle.com/technetwork/articles/javase/single-jar-141905.html

需要修改

<manifest> 
    <attribute name="Main-Class" value="${main.class}"/> 
</manifest> 

,並更改爲

<manifest> 
    CHANGE application.MainClass to 
    <attribute name="JavaFX-Application-Class" value="application.MainClass" /> 
    <attribute name="Main-Class" value="com/javafx/main/Main" /> 
</manifest> 

不過,聽甲骨文上面使我獲得與外部單一的JavaFX罐頭在一起。

相關問題