[精讚] [會員登入]
49

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

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

分享此文連結 http://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

你可能感興趣的文章

【Python3】11 - 字典(Dictionary)的使用範例 python3的幾個字典使用範例,改寫自他人perl的範例

【C++】使用SFML創建新視窗和新增圖標(ICON)並隱藏DOS 筆記,怕自己以後忘記怎麼創建並開啓一個新視窗

【C++】SFML安裝於Microsoft Visual Studio 2019 此方法僅適用單個C++專案,因為一次就適用整台電腦的方式有人寫了,而且寫得非常不錯。

【Maven】如何創建一個簡單可執行的JAR檔 滿重要的一個小功能,畢竟有時候是要傳遞的是JAR檔,而不是直接透過Maven直接部屬之類的

【Linux】[CentOS 8] How to update sudo instruction The last time I wanted to update the sudo command should be 2017, right? It's 2021 in a blink of an

【C++】使用SFML製作讓方塊落下的畫面 從開啟新視窗延伸過來的應用(?),配合上一篇所使用到開啟一個可渲染視窗的那堆程式碼的延伸。

【Linux】[CentOS 8]如何更新sudo指令 上次會想要更新sudo這個指令的時間應該是2017年了吧?轉眼間就2021了耶

【C++】一些好用的C++小功能 —— 貳 承襲上一篇的C++小功能,筆記下來以免自己以後忘記了。

【Maven / Jython】建立可直接執行的JAR檔案 以小編的前一篇文章為基礎,加了一些新東西進去,就變成另一個樣貌了

【C】〔無條件捨去〕如何忽略float數據 直接儲存成int型態(數據100%不失真) a148: You Cannot Pass?! 解題時所意外研究出來的神奇寫法,懂了原理之後要自行改寫成四捨五入或無條件進位應該就簡單了吧!

我有話要說


限制:留言最高字數1000字,超過部分會被截掉。請注意:留言不可帶有網址,會被濾掉。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

【分享、整合串】什麼?!高捷少女竟然有二創小說!! 由時零宇宙大大在巴哈上面連載的二創高捷少女小說,就讓我們來看看,究竟在時零大大的巧手下,高捷少女們會擦出什麼樣的火花吧!

高捷少女:小穹與果仁巧克力㊤ 阿敏突然輕笑一聲,從櫃臺拿來一個塑膠餐盒,打開給大家看。「這是小穹烤的餅乾,妳們吃吃看就知道她為什麼不想講了。」小穹變得緊張起來。「阿敏,妳怎麼還留著呀?」艾米莉亞、婕兒與耐耐各自拿了一塊,把夾著奶油

高捷少女:小穹與果仁巧克力㊥ 艾咪臉上泛起笑容說:「妳知道嗎?就跟花語一樣,每一種巧克力也都有各自的涵義:薄荷巧克力代表初戀;卡通巧克力代表天真爛漫;而果仁巧克力代表的是窩心,還有想陪伴對方的心情,這在德國是女生之間在慶生時會彼此

高捷少女:小穹與果仁巧克力㊦ 「如果妳跟一個女生同班三年,看過她午休流口水跟狼吞虎嚥地吃午餐,就算變成高捷代言人,也很難把她當女神的啦!」她說,小穹氣得搶走她義大利麵裡的蝦子,其他人笑得花枝招展。

高捷少女:地下城的探險少女(終)  小穹眨眨眼睛,然後說了出來。「其實,從剛剛開始,我就在想了……是在看過這本日記之後。」她拿出日記。「我想……我們尋找寶藏的想法,是不是真的正確的?」「怎麼說呢?」耐耐好奇地問。「這個埋藏寶藏的人,在