簡體   English   中英

如何在單個.JAR中簽署和部署JavaFX應用程序?

[英]How can I sign and deploy a JavaFX application into a single .JAR?

我還在學習JavaFX的細節。 一個主要的區別是在dist文件夾(除了庫)之外,我發現.jar文件,HTML文件和JNLP文件,對我來說既不是也沒有用(這將是一個桌面應用程序)。

我找到了以下內容(由於敏感/無關信息,屬性被省略):

<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應用程序執行相同的操作時,它會自行調整:

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

發現它不起作用我並不完全驚訝,但這有點問題。 我做了一些關於可能部署“自包含”應用程序的研究,但這不符合我們的需求。 我的雇主以一定的代價購買了Comodo證書,我很快就碰到了一堵牆,看起來因為蘋果惡作劇(除非我在這個推定中弄錯了)你必須加入他們的開發者俱樂部,以低廉的成本100美元一個一年(沒有發生)。 我並沒有特別為蘋果平台做開發。 我做Java開發。 無論如何,如果我是正確的,那對我們不起作用,那么Windows,Linux和Mac的自包含部署就會出來(再次,如果我是正確的)。

我希望這很簡單。

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

編輯1:好的,所以肯定說得太早了。 不是很接近答案。 我已經嘗試過frankenstein我所知道的關於編譯和簽署常規JAR文件的知識,以便包含所有庫,並且該符號成功地完成了我能夠從手冊中選擇的內容 我所擁有的是大雜燴和失敗。 除了主.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}"/>

這就是我必須展示的時間。 如果有人能從中收集到可能讓我走上正軌的東西(如果我甚至接近,我感覺不像我),那將是非常棒的。

在將我的頭骨和其中的內容砸成一種難以辨認的連貫思想之后,我已經設法編寫了一個腳本,完成了我要完成的任務。 其中大部分來自其他人的貢獻和咨詢文件 另一個主要貢獻在這里找到(最后一個評論在線程,它鏈接到另一個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個目標可以處理拉鏈,然后設置拉鏈,最后一個用於演唱最后一個jar:

<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>

我無法解釋這一切,因為我在這個問題上遠不是一位專家。 我基本能夠提取什么,我一直在尋找從示例代碼的意義上,我發現了來源,並把它在一起,得到這樣的:那是半有用的信息最后一個位是這個 ,但是請注意,這並不使用one-jar(我嘗試使用one-jar但它沒有用。它沒有引入CSS或應用它)。

還有一點警告: 這對我有用 我不能保證它會適合你,但我想用它來修補它會產生類似於我的結果(一個.JAR JavaFX應用程序運行在你放的地方)。

Oracle發言: 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>

但是聽上面的Oracle讓我得到了一個帶有外部jar的JavaFX。

我嘗試了你的build.xml示例,但未能使它工作。

但是,我確實找到了使用Eclipse的替代方法。

  1. 在Eclipse中打開JavaFX項目。
  2. 右鍵單擊您的項目並將其導出為可運行的JAR文件。
  3. 將所需的庫提取到生成的JAR中。

在此輸入圖像描述

  1. 使用標准jar簽名者簽署可運行的JAR。

為此,您需要先創建一個密鑰庫:

keytool -genkey -keyalg RSA -alias Aubrey -keystore keystore.jks -storepass YourPassword

然后簽名就像這樣:

jarsigner -keystore c:\path\to\your\keystore.jks -storepass YourPassword c:\path\to\your\file.jar Aubrey
  1. 最后,創建一個javafx jnlp文件。 並將您簽名的jar和jnlp上傳到您的服務器。

例如:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" codebase="http://aubreigo.info/java/" href="FX-People.jnlp">
<information>
<title>FX-People</title>
<vendor>aubrey</vendor>
<description>Google Contacts Viewer</description>
<offline-allowed/>
</information>

<security>
<all-permissions/>
</security>

<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="FX-People.jar" size="109545" download="eager" />
</resources>

<applet-desc  width="800" height="600" main-class="com.javafx.main.NoJavaFXFallback"  name="FX-People" >
<param name="requiredFXVersion" value="8.0+"/>
</applet-desc>
<jfx:javafx-desc  width="800" height="600" main-class="fx.contacts.FXContacts"  name="FX-People" />
<update check="always"/>
</jnlp>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM