如何制作一个简单的自解压 jar 文件?
How can i make a simple self extracting jar file?
基本上我需要一个 jar 安装程序,它将 cert.pem
和 cloudflare.exe
从自身提取到一个临时目录中,并且不使用任何第 3 方库。
我试图找到一些类似的问题,但我只找到过时的问题,或者没有用的问题。
jar文件内容供参考:
一个自解压 jar(仍然需要 java 安装)
package com.Whosebug.joopeggen;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.*;
import java.security.ProtectionDomain;
import java.util.Map;
public class App {
public static void main(String[] args) {
try {
new App().extractSelf();
} catch (IOException | URISyntaxException| IllegalStateException e) {
e.printStackTrace();
System.exit(1);
}
}
提取使用class信息获取jar源URLfile: ... .jar
.
private void extractSelf() throws IOException, URISyntaxException {
ProtectionDomain protectionDomain = App.class.getProtectionDomain();
URL fileUrl = protectionDomain.getCodeSource().getLocation();
// "file: ... .jar"
Path jarDir = Paths.get(fileUrl.toURI()).getParent();
URI jarFileUri = URI.create("jar:" + fileUrl);
Map<String, Object> env = Map.of("Encode", "UTF-8");
FileSystem zipFS = FileSystems.newFileSystem(jarFileUri, env);
Path root = zipFS.getPath("/");
Files.list(root)
.filter(path -> Files.isRegularFile(path))
.forEach(path -> {
try {
Path extractedPath = jarDir.resolve(path.getFileName().toString());
System.out.println("* " + extractedPath);
Files.copy(path, extractedPath);
} catch (IOException e) {
throw new IllegalStateException(path.getFileName().toString(), e);
}
});
}
}
主要class需要在META-INF/MANIFEST.MF.
里面
我使用 maven 进行构建。
- src/main/java - java 来源的根目录
- com/Whosebug/joopeggen - 包
- src/main/resources - 资源文件的根目录
- cert.pem
- cloudflare.exe
您可能不熟悉 maven,Project-Object-Model XML, pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.Whosebug.joopeggen</groupId>
<artifactId>selfextracting</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<!-- exec:exec to start the jar instead of generated classes. -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>maven</executable>
</configuration>
</plugin>
<plugin>
<!-- To fill META-INF/MANIFEST.MF with Main-Class. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.Whosebug.joopeggen.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
虽然涉及到很多方面,但代码只需要几行(大约 17 行)。
基本上我需要一个 jar 安装程序,它将 cert.pem
和 cloudflare.exe
从自身提取到一个临时目录中,并且不使用任何第 3 方库。
我试图找到一些类似的问题,但我只找到过时的问题,或者没有用的问题。
jar文件内容供参考:
一个自解压 jar(仍然需要 java 安装)
package com.Whosebug.joopeggen;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.*;
import java.security.ProtectionDomain;
import java.util.Map;
public class App {
public static void main(String[] args) {
try {
new App().extractSelf();
} catch (IOException | URISyntaxException| IllegalStateException e) {
e.printStackTrace();
System.exit(1);
}
}
提取使用class信息获取jar源URLfile: ... .jar
.
private void extractSelf() throws IOException, URISyntaxException {
ProtectionDomain protectionDomain = App.class.getProtectionDomain();
URL fileUrl = protectionDomain.getCodeSource().getLocation();
// "file: ... .jar"
Path jarDir = Paths.get(fileUrl.toURI()).getParent();
URI jarFileUri = URI.create("jar:" + fileUrl);
Map<String, Object> env = Map.of("Encode", "UTF-8");
FileSystem zipFS = FileSystems.newFileSystem(jarFileUri, env);
Path root = zipFS.getPath("/");
Files.list(root)
.filter(path -> Files.isRegularFile(path))
.forEach(path -> {
try {
Path extractedPath = jarDir.resolve(path.getFileName().toString());
System.out.println("* " + extractedPath);
Files.copy(path, extractedPath);
} catch (IOException e) {
throw new IllegalStateException(path.getFileName().toString(), e);
}
});
}
}
主要class需要在META-INF/MANIFEST.MF.
里面我使用 maven 进行构建。
- src/main/java - java 来源的根目录
- com/Whosebug/joopeggen - 包
- src/main/resources - 资源文件的根目录
- cert.pem
- cloudflare.exe
您可能不熟悉 maven,Project-Object-Model XML, pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.Whosebug.joopeggen</groupId>
<artifactId>selfextracting</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<!-- exec:exec to start the jar instead of generated classes. -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>maven</executable>
</configuration>
</plugin>
<plugin>
<!-- To fill META-INF/MANIFEST.MF with Main-Class. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.Whosebug.joopeggen.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
虽然涉及到很多方面,但代码只需要几行(大约 17 行)。