[精讚] [會員登入]
873

【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

你可能感興趣的文章

【C】(%c, %d)解決讀取字元時的緩衝區殘留 不解決就會莫名其妙地冒出一些莫名其妙的東西

【Docker&Wildfly】(bitnami/wildfly)如何從零開始創建網頁伺服器 使用他人的 docker image 來架設我們的 wildfly web server

【Discord bot 2.0.1】(discord.ui.View)如何將舊機器人升級至目前最新版本 很多時候升級軟體是為了讓別人覺得你的程式很先進,但這次卻是因為要使用某個新功能

【C++】class練習 — 檢測該字串是否為迴圈 第一次的C++結構式寫法,雖然以後應該會見怪不怪,但畢竟是第一次所以還是想保存下來

【C++】使用struct array和一維int array模擬二維int array 主要是因為用sort去排序int array的二維陣列小編懶得研究,於是就研究了一種維持一維陣列但是有二維陣列效果的程式,小編就廢~~

【Kali Linux】[history -c]如何清除歷史記錄 非bash環境會使history部分功能變的非法

我有話要說

>>

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

訪客留言

[無留言]

隨機好文

【英翻中歌詞】(二創歌)東方妖妖夢-人形裁判 ~玩弄人偶的少女 人形裁判 ~ 人の形弄びし少女 很久很久以前,在一個神奇的異地,住著一位少女,十分惹人憐愛 她的皮膚就像陶瓷一樣潔白,眼睛就像藍色寶珠般明亮

【數學】徐氏數學簡明講義(三) 第二章 直線與園 P2.1-15 Q6 6.平面上有一四邊形ABCD其頂點分別為(0,0)、(2,1)、(3,4)、(-1,5),此平面上另有P,Q兩點,求 :

【數學】徐氏數學簡明講義(三) 第二章 直線與園 P2.1-15 Q12 12.已知聯立方程式恰有一解(x,y) = (1,2),   則的解為(x,y) = ? 解:

【數學】線性規劃——題型演練 某公司招聘新員工,共有800人應徵參加筆試。筆試場地借用某高中教室,該校租借的大教室有42間,每間可容納40人,每間租金

小穹‧動畫化‧體驗記① 某個星期六的下午,娟姊所在的某間咖啡廳內,傳來了一陣雀躍的交談聲。「這是當然的啊。」娟姊高興地說:「上級真是太不夠意思了,居然現在才告訴我。」「為執行長說您跟她們一定會同意,所以才事先決定好計畫的大要