Java项目如何打jar包?

使用Maven执行mvn package或Gradle运行jar任务自动打包;在IDEA/Eclipse中通过导出功能生成可执行JAR;手动使用jar cvfe命令指定主类并包含编译后的class文件。

核心打包方法

使用JDK自带命令(适合简单项目)

# 编译所有.java文件
javac -d ./out src/*.java
# 打包编译后的class文件
jar cvf myapp.jar -C out/ .
# 指定主类(可执行JAR)
jar cvfe myapp.jar com.example.MainClass -C out/ .

说明

Java项目如何打jar包?

  • -d:指定编译输出目录
  • cvf:创建(c)、显示详情(v)、指定文件名(f)
  • e:指定入口主类(MANIFEST.MF中自动添加Main-Class

使用Maven(标准项目管理)

步骤

  1. pom.xml中添加打包配置:
    <build>
     <plugins>
         <!-- 基础打包插件 -->
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-jar-plugin</artifactId>
             <version>3.3.0</version>
             <configuration>
                 <archive>
                     <manifest>
                         <mainClass>com.example.Main</mainClass> <!-- 指定主类 -->
                     </manifest>
                 </archive>
             </configuration>
         </plugin>
     </plugins>
    </build>
  2. 执行打包命令:
    mvn clean package  # 输出在target目录

生成Fat Jar(包含依赖)

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.6.0</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <mainClass>com.example.Main</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

使用Gradle(灵活构建)

基础配置build.gradle):

Java项目如何打jar包?

plugins {
    id 'java'
}
jar {
    manifest {
        attributes 'Main-Class': 'com.example.Main'
    }
}

执行打包:

gradle jar  # 输出在build/libs

生成Fat Jar

plugins {
    id 'com.github.johnrengelman.shadow' version '8.1.1'  // 添加Shadow插件
}
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
    archiveBaseName = 'myapp'
    archiveClassifier = 'all'
    mergeServiceFiles()
}

运行:

Java项目如何打jar包?

gradle shadowJar

关键注意事项

  1. MANIFEST.MF文件
    • 必须包含Main-Class头声明可执行JAR
    • 格式要求:Main-Class: com.example.Main(末尾换行符!)
  2. 依赖处理
    • Fat Jar:适用于简单应用(Maven Assembly/Gradle Shadow)
    • 避免依赖冲突:使用maven-shade-pluginrelocate重命名包
  3. 模块化项目(Java 9+)
    • 添加module-info.java
    • 使用jlinkjpackage生成自定义运行时

验证JAR是否可用

# 检查文件结构
jar tf myapp.jar
# 运行可执行JAR
java -jar myapp.jar
# 排查类加载问题
java -verbose:class -jar myapp.jar | grep "Loaded"

常见问题解决

  • “no main manifest attribute”
    缺失Main-Class声明,检查MANIFEST.MF或构建配置。
  • ClassNotFoundException
    依赖未正确打包(Fat Jar配置错误)。
  • 版本冲突
    使用mvn dependency:tree分析依赖树。
  • 签名问题
    删除签名文件:zip -d myapp.jar 'META-INF/*.SF' 'META-INF/*.RSA'

最佳实践建议

  1. 分离依赖:生产环境推荐将依赖库放入/lib目录,通过Class-Path引用:
    Class-Path: lib/dependency1.jar lib/dependency2.jar
  2. 版本管理:JAR文件名包含版本号(如myapp-1.0.0.jar)。
  3. 安全扫描:使用OWASP Dependency-Check扫描依赖漏洞。
  4. 持续集成:在Jenkins/GitHub Actions中自动化打包流程。

引用说明参考Oracle官方文档JAR文件规范Maven官方指南Gradle用户手册,并基于Java 17 LTS版本验证,构建工具版本号截至2025年10月有效,建议定期检查更新。

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/40539.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年6月27日 22:32
下一篇 2025年6月27日 22:38

相关推荐

  • Java如何生成压缩文件?

    在Java中导出压缩文件主要使用ZipOutputStream类,首先创建FileOutputStream,再包装为ZipOutputStream,遍历文件列表,为每个文件创建ZipEntry并放入流中,通过BufferedInputStream读取文件内容写入,最后关闭所有流资源确保文件正确生成。

    2025年6月12日
    100
  • Java如何输出对象个数?

    在Java中输出对象个数,可通过静态计数器实现:在类中定义static int count,构造方法中count++,析构方法中count–,调用类名.count即可输出当前对象数量。

    2025年5月30日
    600
  • Java如何保存txt文件?

    在Java中保存文本到txt文件,可使用FileWriter、BufferedWriter或Files.write()方法,示例代码:,“java,try (BufferedWriter writer = new BufferedWriter(new FileWriter(“output.txt”))) {, writer.write(“要保存的文本内容”);,},“,此方法自动处理编码和资源关闭,确保数据正确写入文件。

    2025年6月8日
    100
  • Java插件下载开发教程步骤

    使用Java开发下载插件需实现网络连接、多线程处理和文件存储功能,通过HttpURLConnection或HttpClient发起请求,支持断点续传和进度监控,确保异常捕获与资源释放。

    2025年6月25日
    000
  • 怎么在Java中给字符串赋值?

    在Java中,可以通过双引号直接赋值(如 String s = “Hello”)或使用new关键字创建新对象(如 String s = new String(“Hello”)),字符串是不可变对象,每次赋值实际指向新内存地址。

    2025年6月27日
    000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN