[精讚] [會員登入]
491

【Maven / Jython】建立可直接執行的JAR檔案

以小編的前一篇文章為基礎,加了一些新東西進去,就變成另一個樣貌了

分享此文連結 //n.sfs.tw/15518

分享連結 【Maven / Jython】建立可直接執行的JAR檔案@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2021-11-30 15:18:08 最後編修
2021-11-28 23:36:10 By 過路君子
 

大家好,這裡是因為感覺有趣所以不小心產生出這玩意的小編過路君子

但也花了不少時間在這東西上面,最後的 --add-opens問題沒能解決,就...留給其他高手來解答吧

 

 

那這篇所使用的概念的基底就是這篇: 【Maven】如何創建一個簡單可執行的JAR檔@小編過路君子

基本上就是對 pom.xml做一點「小小的」改動,那我們照慣例,直接就先上目錄結構吧。

(所有圖片點擊都可以放大、變高清)

 

可以發現目錄結構突然變得又臭又長,那是因為我們將整個 python的 Lib都搬進來了。

雖然現在暫時還用不到,但是之後開始撰寫 python的時候可能會要 "import time"之類的,那平時我們在執行 python的時候,編譯器會自動去我們 python所在的目錄下面找尋我們所 import進來的東西。

但今天我們不但是用 java來呼叫並執行 python,還打包成了 jar檔準備丟給別人,撇開對方伺服器裡面沒有 python的問題,我們根本不知道對方 python所在的目錄在哪裡!所以必須手動夾帶進去 jar檔裡面。

那這裡有一個要特別注意的點,除非有特別設定過 Maven,否則我們之後撰寫的所有 .py檔案都必須放在 resources下,要不然 Maven不會將其打包進去 jar檔裡面。

至於 outside.py和 in.py可以先忽略,這是小編另外一篇(【Maven / Jython】如何在JAVA裡import其他python檔案和新增資源路徑)在講如何導入自行撰寫的 .py檔案所會用到的素材,在這邊用不到。

 

那現在我們就是要先找出 python的 lib在哪裡。

Linux     whereis python

 

以小編來說,小編的 python所在的目錄在 /usr/lib64/python3.6/下,所以小編就將這個目錄下的所有檔案複製到 ./src/main/resources/python3.6/Lib/下。

Linux     mkdir -p ./src/main/resources/python3.6/Lib/
    cp -r /usr/lib64/python3.6/* ./src/main/resources/python3.6/Lib/

※注意檔案權限,如果檔案權限為 "-rw-r--r--. 1 root root"之類的,記得要更改檔案的擁有者。

 

這邊有一點要非常注意,就是目錄路徑最後一定要以 Lib/做結尾,這是因為等等我們在設置 python.home的時候,系統會自動加上 Lib/,所以如果我們沒有以 Lib/結尾照樣找不到。

畢竟我們基底還是 java,在使用 python預設某些函式庫的時候還是會出問題,例如:os, asyncio等等,不過問題不大,這些基本上 java都有相對應的函式庫可以取代;下面為 import os的時候所引發的錯誤。

Exception in thread "main"
Exception: org.python.core.PySyntaxError thrown from the UncaughtExceptionHandler in thread  "main"

 

將所有檔案複製完成後,就可以來添加 index.java的內容囉。

其中第 22行的 python.home如果各位有去查其他人所整理的資料應該會發現常常就只寫了一行 "path to the Lib folder",當初小編也是搞了很久才弄清楚這東西要怎麼設定,所以才會特別拉出來講。

那根據小編剛剛上面的設置 python的家目錄在 ./src/main/resources/python3.6/下,所以我們就將那串寫入就可以了,程式在執行的時候實際會去 ./src/main/resources/python3.6/Lib下找尋我們所 import的檔案。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package editor.passing.jinzan;

import java.util.*;
import org.python.util.PythonInterpreter;

public class index
{
    public static void main(String[] args)
    {
        jythonInit();

        PythonInterpreter python = new PythonInterpreter();
        python.exec("print('Hello World!')");
    }

    private static void jythonInit()
    {
        Properties init = new Properties();
        init.put("python.home", "./src/main/resources/python36/");
        init.put("python.console.encoding", "UTF-8");
        init.put("python.security.respectJavaAccessibility", "false");
        init.put("python.import.site", "false");
        PythonInterpreter.initialize(System.getProperties(), init, new String[0]);
    }
}

 

可以感覺到光是 index.java就長大了不少,雖然和介紹如何打包成 Jar檔案那篇執行完全一樣的功能,在螢幕上顯示「Hello World!」。

pom.xml 基本上只加了 dependency和對 maven-shade-plugin的 <configuration>標籤裡做變動而已,其他的部分都一樣。

對了,實際上 <filters></filters> 這個標籤可以不用加,不會影響最終 Jar檔案的執行,但是會跳出一堆警告,如果覺得顯示警告也沒關係的話,可以把這個標籤連同子標籤一起拔掉。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";;;;;;;;;;;;;>
	<modelVersion>4.0.0</modelVersion>

	<groupId>editor.passing.jinzan</groupId>
	<artifactId>packageJAR</artifactId>
	<version>1.0.0</version>

	<name>pixiJS-web Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<packaging>jar</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.python</groupId>
			<artifactId>jython</artifactId>
			<version>2.7.2</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>3.2.4</version>
				<executions>
					<execution>
						<phase>package</phase>

						<goals>
							<goal>shade</goal>
						</goals>

						<configuration>
							<transformers>
								<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<mainClass>editor.passing.jinzan.index</mainClass>
								</transformer>
							</transformers>
							<filters>
								<filter>
									<artifact>*:*</artifact>
									<excludes>
										<exclude>module-info.class</exclude>
										<exclude>META-INF/*.MF</exclude>
									</excludes>
								</filter>
							</filters>
							<createDependencyReducedPom>false</createDependencyReducedPom>
						</configuration>

					</execution>
				</executions>
			</plugin>

			<plugin>
				<artifactId>maven-clean-plugin</artifactId>
				<version>3.1.0</version>
			</plugin>
			
			<plugin>
				<artifactId>maven-resources-plugin</artifactId>
				<version>3.0.2</version>
			</plugin>
			<plugin>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.1</version>
			</plugin>
			<plugin>
				<artifactId>maven-install-plugin</artifactId>
				<version>2.5.2</version>
			</plugin>
			<plugin>
				<artifactId>maven-deploy-plugin</artifactId>
				<version>2.8.2</version>
			</plugin>
			<plugin>
				<artifactId>maven-site-plugin</artifactId>
				<version>3.7.1</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
			</plugin>

		</plugins>
	</build>

</project>

 

然後接著做一個簡單的打包動作。

Linux     mvn package

 

打包好的 Jar檔依舊躺在 tar裡面,但是,這一次不同的是,只單純加上 -jar來執行還是會出錯。

要再多加上一個 --add-opens才可以正確執行 Jar檔。

Linux     java --add-opens java.base/java.lang=ALL-UNNAMED -jar target/packageJAR-1.0.0.jar

 

 

 

後記

小編會想要建立一個這麼麻煩的 Jar檔很大一部分原因是要拿來做實驗,小編可不想每次打包成 War檔之後還要進行 deploy的動作,雖然好像在 Maven下都是一個指令解決......

現在就是祈禱之後小編要寫的程式能成功用 Jar檔執行起來,如果有成功應該也會發一篇文章,會把前幾篇提到的大部分內容混合起來。

END

你可能感興趣的文章

【Wicket】[nonce]如何導入css以及javascript 如果只是用一般的 HTML link 或是 script 標籤來寫,會被 CSP 擋住,禁止加載資源,那我們除了關閉 CSP 以外還有沒有辦法來解決呢?

【教程】[HTML](進階版)如何在手機上編輯電子書(epub)預覽介面 可能會有人認為電子書(epub)只能用電腦來開啟、編輯,其實不是的,手機也可以編輯喔!

【Firefox \ Maven】[Headless](Linux) 如何使用Maven打包並驅動Firefox 有時候我們需要取得渲染後的網頁,當然是直接呼叫瀏覽器出來用啦

【ThinkSpeak】一個IoT數據分析(IoT analytics)及呈現的網站 世界上有著各式各樣的需求,因而誕生出了各式各樣的網站,絕對不是沒有人提供,而是你不知道哪裡有這東西

【Socket】(Linux / Python 3)兩不同系統的主機之間如何使用Socket相互溝通 How to connect two different computer use Socket

【JSON In Java】如何快速產生JSON 身為三十年老程式語言,當然對Json有不錯的支援,那究竟該如何使用呢

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

高捷少女:地下城的探險少女① 婕兒心中一奇,便走上前看著仔細。那塊凹進去的地方中心大約三公分厚,越往邊緣就越淺,圓型直徑十五公分。婕兒拿出銅盤對比一下,發現兩者大小竟然一致,銅盤似乎能夠完整的嵌進去。     婕兒看著凹槽,心中

高捷少女:地下城的探險少女② 「等我一下喔,我好像有帶去漬的清潔噴霧。」婕兒翻翻飛揚,拿出噴霧劑給小穹,小穹趕緊對著汙漬噴了噴,紅茶漬果然乾淨了許多。「婕兒,謝謝妳。來,還妳。」小穹感謝地把噴霧還給她,卻發現婕兒盯著打開的飛揚,一

高捷少女:美麗島的守護者① 婕兒跟耐耐嚇得臉色發白。「耐耐,小穹有這方面的愛好喔?」婕兒小聲地說。耐耐默默的拿出筆記本,臉上浮現一層微笑:「這麼大的新聞,要趕快記下來!」

高捷少女:美麗島的守護者② 這是在亦晨離開前的下午拍的,當時亦晨在美麗島跟小穹艾米等人在美麗島散步,為離開前補充一些回憶,這時剛好經過的小雅被艾米抓過來,做為同樣是高捷新人的她倆一同拍了一張紀念照。說起來她跟亦晨並不太熟,不過也

高捷少女:耐耐的新年驚喜(終) 他的話說到一半,便被一陣響亮的哭聲打住了,是從產房中的傳來的。聽起來就像嬰兒的哭聲。 婕兒、小穹跟艾米也被哭聲吵醒,婕兒揉揉眼睛,看向呆若木雞的耐耐父女。「剛剛的聲音,該不會是……」