2012-07-26

可執行的 Jar(Executable Jar)

Web 程式寫太多,都不知道桌面程式要怎寫。

先直接跳到終點前,寫完程式了,怎麼交付給使用者,總不能給一堆 class 檔吧,不能作成 exe 檔(使用 Launch4j 將 jar 包成 exe 檔),至少要作成可執行的 jar 檔。

產生「可執行的 jar 檔」

產生 jar 檔沒問題,尤其是用 Maven,下個 mvn package 就好了,但是不會自動執行啊,問題在於要從哪個 class 執行,也就是說哪個 class 有 main。

只要在 jar 檔裡建個 META-INF/MANIFST.MF 檔案,並填入以下內容就可以了。

Main-Class: idv.neil.executableJar.HelloEJ
 
記得要斷行。

手動產生有點麻煩,Maven 幫我們想過了,只要在 pom.xml 裡加上以下的設定。
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.7.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer
                  implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>idv.neil.executableJar.HelloEJ</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
再執行 mvn package,產生的 jar 檔裡就有 Main-Class 定義了。

最後要怎麼執行「可執行的 jar 檔」?

最簡單就是使用 javaw,在安裝 JRE 之後會將 jar 關聯給 javaw,所以若沒有更改關聯檔案,只要雙點 jar 就可以了。

或者從 Command Line 執行:
java -jar TheJarFile.jar

又或者寫個 bat 檔,將以下內容貼到記事本存成 run.bat,雙點 run.bat 也可以執行。
java -jar {FULL_PATH}/TheJarFile.jar

如果用到其他 library 呢?

Maven 也想好了,只要下個 mvn package,會把 pom.xml 定義用到的 dependency 通通包到 jar 檔裡。

怎麼讀取外部檔案?
public class HelloEJ {

  public static void main(String[] args) {
    String string = StringUtils.leftPad("Hello world", 20, '.');
    try {
      // 與 jar 檔同位置
      string = FileUtils.readFileToString(new File("a.txt"));

      // jar 檔內第一層,也就是與 package idv 同位置
      InputStream is = HelloEJ.class.getResourceAsStream("/a.txt");
      string = IOUtils.toString(is);
      IOUtils.closeQuietly(is);
    }
    catch (IOException e) {
      e.printStackTrace();
      string = e.getLocalizedMessage();
    }
    show(string);
  }

  private static void show(String string) {
    Frame f = new Frame();
    f.addWindowListener(new WindowAdapter() {

      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    f.add(new Label(string));
    f.setSize(200, 200);
    f.setVisible(true);
  }
}
---

沒有留言:

張貼留言