开发者

Java项目打包从JAR到Docker的全方位指南

目录
  • ​一、Java打包工具全景图
  • 二、传统JAR打包详解
    • 2.1 项目结构准备
    • 2.2 手动打包实战
    • 2.3 自动化构建脚本
  • 三、Maven标准化打包
    • 3.1 标准Maven项目结构
    • 3.2 基础pom.XML配置
    • 3.3 创建可执行JAR的三种方式
      • 方式一:使用maven-jar-plugin(依赖外置)
      • 方式二:使用maven-assembly-plugin(胖JAR)
      • 方式三:使用maven-shade-plugin(推荐)
    • 3.4 常用Maven命令
    • 四、Web应用WAR包打包
      • 4.1 Web项目结构
        • 4.2 WAR打包配置
          • 4.3 Spring Boot外部容器部署
          • 五、Gradle现代化构建
            • 5.1 基础build.gradle配置
              • 5.2 创建胖JAR
                • 5.3 常用Gradle命令
                • 六、docker容器化部署
                  • 6.1 多阶段构建Dockerfilehttp://www.devze.com
                    • 6.2 Docker Compose编排
                      • 6.3 容器操作命令
                      • 七、高级打包技巧
                        • 7.1 使用jpackage创建原生安装包(JDK 14+)
                          • 7.2 GraalVM原生镜像
                          • 八、最佳实践总结
                            • 8.1 版本管理
                              • 8.2 安全考虑
                                • 8.3 性能优化
                                  • 8.4 CI/CD集成示例
                                  • 结语

                                    ​一、Java打包工具全景图

                                    在开始具体打包之前,我们先了解下主流的Java打包工具及其适用场景:

                                    工具适用场景特点输出格式
                                    javac + jar简单学习项目JDK内置,无需额外配置JAR
                                    Maven企业级项目强大的依赖管理和生命周期JAR, WAR
                                    Gradle复杂大型项目灵活配置,构建性能高JAR, WAR, 多种格式
                                    Spring Boot Maven PluginSpring Boot应用内嵌服务器,开箱即用Executable JAR
                                    jpackage桌面应用程序生成原生安装包EXE, DMG, DEB
                                    Docker微服务部署环境隔离,持续交付Dhttp://www.devze.comocker Image

                                    二、传统JAR打包详解

                                    2.1 项目结构准备

                                    一个标准的Java项目结构如下:

                                    MyApp/
                                    ├── src/
                                    │   └── com/example/
                                    │       ├── Main.java
                                    │       └── util/
                                    │           └── StringUtil.java
                                    ├── lib/ (第三方依赖)
                                    └── resources/ (配置文件)
                                    

                                    2.2 手动打包实战

                                    对于简单的项目,我们可以使用JDK自带的工具手动打包:

                                    # 1. 编译Java源代码
                                    javac -d build/classes src/com/example/**/*.java
                                    
                                    # 2. 创建清单文件(MANIFEST.MF)
                                    cat > MANIFEST.MF << EOF
                                    Manifest-Version: 1.0
                                    Main-Class: com.example.Main
                                    Created-By: Java Packager
                                    EOF
                                    
                                    # 3. 打包成JAR文件
                                    jar cfm myapp.jar MANIFEST.MF -C build/classes .
                                    
                                    # 4. 运行应用
                                    java -jar myapp.jar
                                    

                                    2.3 自动化构建脚本

                                    为了提高效率,我们可以编写构建脚本:

                                    #!/bin/bash
                                    # build.sh - Java项目自动构建脚本
                                    
                                    echo " 开始构建Java项目..."
                                    
                                    # 清理构建目rnuxA录
                                    rm -rf build
                                    mkdir -p build/classes
                                    
                                    # 编译源码
                                    echo " 编译Java源码..."
                                    javac -d build/classes -sourcepath src src/com/example/**/*.java
                                    
                                    # 拷贝资源文件
                                    echo " 拷贝资源文件..."
                                    cp -r resources/* build/classes/
                                    
                                    # 创建清单文件
                                    echo " 生成清单文件..."
                                    cat > MANIFEST.MF << EOF
                                    Manifest-Version: 1.0
                                    Main-Class: com.example.Main
                                    Class-Path: $(find lib -name "*.jar" | tr '\n' ' ')
                                    Build-Time: $(date)
                                    EOF
                                    
                                    # 打包JAR
                                    echo " 打包JAR文件..."
                                    jar cfm myapp.jar MANIFEST.MF -C build/classes .
                                    
                                    # 清理临时文件
                                    rm MANIFEST.MF
                                    
                                    echo "✅ 构建完成!输出文件: myapp.jar"
                                    

                                    三、Maven标准化打包

                                    Maven是Java领域最流行的构建工具,提供了标准化的项目结构和构建流程。

                                    3.1 标准Maven项目结构

                                    project/
                                    ├── pom.xml
                                    ├── src/
                                    │   ├── main/
                                    │   │   ├── java/ (Java源代码)
                                    │   │   │   └── com/example/
                                    │   │   │       ├── Main.java
                                    │   │   │       └── service/
                                    │   │   └── resources/ (资源文件)
                                    │   │       ├── application.properties
                                    │   │       └── log4j2.xml
                                    │   └── test/ (测试代码)
                                    │       └── java/
                                    └── target/ (构建输出目录)
                                    

                                    3.2 基础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.example</groupId>
                                        <artifactId>myapp</artifactId>
                                        <version>1.0.0</version>
                                        <packaging>jar</packaging>
                                        
                                        <properties>
                                            <!-- 统一版本管理 -->
                                       编程     <java.version>11</java.version>
                                            <maven.compiler.version>3.8.1</maven.compiler.version>
                                            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                                        </properties>
                                        
                                        <dependencies>
                                            <dependency>
                                                <groupId>org.apache.logging.log4j</groupId>
                                                <artifactId>log4j-core</artifactId>
                                                <version>2.17.1</version>
                                            </dependency>
                                        </dependencies>
                                        
                                        <build>
                                            <plugins>
                                                <!-- 编译器插件 -->
                                                <plugin>
                                                    <groupId>org.apache.maven.plugins</groupId>
                                                    <artifactId>maven-compiler-plugin</artifactId>
                                                    <version>${maven.compiler.version}</version>
                                                    <configuration>
                                                        <source>${java.version}</source>
                                                        <target>${java.version}</target>
                                                    </configuration>
                                                </plugin>
                                            </plugins>
                                        </build>
                                    </project>
                                    

                                    3.3 创建可执行JAR的三种方式

                                    方式一:使用maven-jar-plugin(依赖外置)

                                    <plugin>
                                        <groupId>org.apache.maven.plugins</groupId>
                                        <artifactId>maven-jar-plugin</artifactId>
                                        <version>3.2.2</version>
                                        <configuration>
                                            <archive>
                                                <manifest>
                                                    <mainClass>com.example.Main</mainClass>
                                                    <addClasspath>true</addClasspath>
                                                    <classpathPrefix>lib/</classpathPrefix>
                                                </manifest>
                                            </archive>
                                        </configuration>
                                    </plugin>
                                    

                                    方式二:使用maven-assembly-plugin(胖JAR)

                                    <plugin>
                                        <groupId>org.apache.maven.plugins</groupId>
                                        <artifactId>maven-assembly-plugin</artifactId>
                                        <version>3.3.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>
                                    

                                    方式三:使用maven-shade-plugin(推荐)

                                    <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>com.example.Main</mainClass>
                                                        </transformer>
                                                        <!-- 处理Spring配置文件 -->
                                                        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                                            <resource>META-INF/spring.handlers</resource>
                                                        </transformer>
                                                    </transformers>
                                                </configuration>
                                            </execution>
                                        </executions>
                                    </plugin>
                                    

                                    3.4 常用Maven命令

                                    # 清理并打包
                                    mvn clean package
                                    
                                    # 跳过测试打包
                                    mvn clean package -DskipTests
                                    
                                    # 安装到本地仓库
                                    mvn clean install
                                    
                                    # 生成源码包和文档
                                    mvn source:jar javadoc:jar
                                    
                                    # 运行Spring Boot应用
                                    mvn spring-boot:run
                                    

                                    四、Web应用WAR包打包

                                    对于Web应用,我们需要打包成WAR格式部署到Servlet容器。

                                    4.1 Web项目结构

                                    webapp/
                                    ├── pom.xml
                                    ├── src/
                                    │   └── main/
                                    │       ├── java/
                                    │       │   └── com/example/
                                    │       │       ├── controller/
                                    │       │       ├── service/
                                    │       │       └── config/
                                    │       ├── resources/
                                    │       └── webapp/ (Web资源)
                                    │           ├── WEB-INF/
                                    │           │   └── web.xml
                                    │           ├── index.JSP
                                    │           └── static/
                                    │               ├── css/
                                    │               ├── js/
                                    │               └── images/
                                    

                                    4.2 WAR打包配置

                                    <!-- 修改打包方式为war -->
                                    <packaging>war</packaging>
                                    
                                    <build>
                                        <finalName>mywebapp</finalName>
                                        <plugins>
                                            <plugin>
                                                <groupId>org.apache.maven.plugins</groupId>
                                                <artifactId>maven-war-plugin</artifactId>
                                                <version>3.3.1</version>
                                                <configuration>
                                                    <!-- 对于Spring Boot可以忽略web.xml -->
                                                    <failOnMissingWebXml>false</failOnMissingWebXml>
                                                    <warSourceDirectory>src/main/webapp</warSourceDirectory>
                                                </configuration>
                                            </plugin>
                                        </plugins>
                                    </build>
                                    

                                    4.3 Spring Boot外部容器部署

                                    @SpringBootApplication
                                    public class Application extends SpringBootServletInitializer {
                                        
                                        @Override
                                        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
                                            return application.sources(Application.class);
                                        }
                                        
                                        public static void main(String[] args) {
                                            SpringApplication.run(Application.class, args);
                                        }
                                    }
                                    
                                    <!-- 排除内嵌Tomcat,使用外部容器 -->
                                    <dependency>
                                        <groupId>org.springframework.boot</groupId>
                                        <artifactId>spring-boot-starter-tomcat</artifactId>
                                        <scope>provided</scope>
                                    </dependency>
                                    

                                    五、Gradle现代化构建

                                    Gradle以其简洁的DSL和出色的性能受到越来越多开发者的青睐。

                                    5.1 基础build.gradle配置

                                    plugins {
                                        id 'java'
                                        id 'application'
                                    }
                                    
                                    group = 'com.example'
                                    version = '1.0.0'
                                    sourceCompatibility = '11'
                                    
                                    repositories {
                                        mavenCentral()
                                    }
                                    
                                    dependencies {
                                        implementation 'org.springframework.boot:spring-boot-starter-web:2.7.0'
                                        testImplementation 'org.springframework.boot:spring-boot-starter-test:2.7.0'
                                    }
                                    
                                    application {
                                        mainClass = 'com.example.Main'
                                    }
                                    

                                    5.2 创建胖JAR

                                    // 使用Shadow插件创建胖JAR
                                    plugins {
                                        id 'com.github.johnrengelman.shadow' version '7.1.2'
                                    }
                                    
                                    shadowJar {
                                        archiveBaseName.set('myapp')
                                        archiveClassifier.set('')
                                        archiveVersion.set('')
                                        mergeServiceFiles()
                                    }
                                    
                                    // 或者自定义任务
                                    task customFatJar(type: Jar) {
                                        manifest {
                                            attributes 'Main-Class': 'com.example.Main'
                                        }
                                        archiveBaseName = 'myapp-all'
                                        from { 
                                            configurations.runtimeClasspath.collect { 
                                                it.isDirectory() ? it : zipTree(it) 
                                            } 
                                        }
                                        with jar
                                        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
                                    }
                                    

                                    5.3 常用Gradle命令

                                    # 构建项目
                                    ./gradlew build
                                    
                                    # 创建胖JAR
                                    ./gradlew shadowJar
                                    
                                    # 清理构建
                                    ./gradlew clean
                                    
                                    # 运行应用
                                    ./gradlew run
                                    

                                    六、Docker容器化部署

                                    容器化部署已经成为现代应用部署的标准方式。

                                    6.1 多阶段构建Dockerfile

                                    # 第一阶段:构建阶段
                                    FROM maven:3.8.4-openjdk-11 AS builder
                                    WORKDIR /app
                                    
                                    # 拷贝pom文件并下载依赖(利用Docker缓存)
                                    COPY pom.xml .
                                    RUN mvn dependency:go-offline
                                    
                                    # 拷贝源码并构建
                                    COPY src ./src
                                    RUN mvn clean package -DskipTests
                                    
                                    # 第二阶段:运行阶段
                                    FROM openjdk:11-jre-slim
                                    WORKDIR /app
                                    
                                    # 创建非root用户(安全考虑)
                                    RUN groupadd -r spring && useradd -r -g spring spring
                                    USER spring
                                    
                                    # 从构建阶段拷贝JAR文件
                                    COPY --from=builder /app/target/*.jar app.jar
                                    
                                    # 健康检查
                                    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
                                        CMD curl -f http://localhost:8080/actuator/health || exit 1
                                    
                                    # JVM参数优化
                                    ENV JAVA_OPTS="-Xmx512m -Xms256m -XX:+UseG1GC -Djava.security.egd=file:/dev/./urandom"
                                    
                                    # 暴露端口
                                    EXPOSE 8080
                                    
                                    # 启动命令
                                    ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
                                    

                                    6.2 Docker Compose编排

                                    version: '3.8'
                                    
                                    services:
                                      app:
                                        build: .
                                        ports:
                                          - "8080:8080"
                                        environment:
                                          - SPRING_PROFILES_ACTIVE=prod
                                          - DATABASE_URL=jdbc:mysql://db:3306/myapp
                                        depends_on:
                                          - db
                                        networks:
                                          - app-network
                                        deploy:
                                          resources:
                                            limits:
                                              memory: 512M
                                            reservations:
                                              memory: 256M
                                    
                                      db:
                                        image: mysql:8.0
                                        environment:
                                          MYSQL_ROOT_PASSWORD: rootpass
                                          MYSQL_DATABASE: myapp
                                        volumes:
                                          - db_data:/var/lib/mysql
                                        networks:
                                          - app-network
                                    
                                    volumes:
                                      db_data:
                                    
                                    networks:
                                      app-network:
                                        driver: bridge
                                    

                                    6.3 容器操作命令

                                    # 构建镜像
                                    docker build -t myapp:1.0.0 .
                                    
                                    # 运行容器
                                    docker run -d -p 8080:8080 --name myapp myapp:1.0.0
                                    
                                    # 使用Docker Compose
                                    docker-compose up -d
                                    
                                    # 查看日志
                                    docker logs -f myapp
                                    
                                    # 进入容器调试
                                    docker exec -it myapp bash
                                    

                                    七、高级打包技巧

                                    7.1 使用jpackage创建原生安装包(JDK 14+)

                                    # 创建跨平台安装包
                                    jpackage \
                                      --name MyApp \
                                      --input target/ \
                                      --main-jar myapp-1.0.0.jar \
                                      --main-class com.example.Main \
                                      --type app-image \
                                      --dest installers/ \
                                      --java-options '-Xmx256m'
                                    
                                    # Windows特定选项
                                    jpackage --type exe --win-console --icon app.ico
                                    
                                    # MACOS特定选项  
                                    jpackage --type dmg --mac-package-identifier com.example.myapp
                                    
                                    # linux特定选项
                                    jpackage --type deb --linux-package-name myapp
                                    

                                    7.2 GraalVM原生镜像

                                    FROM ghcr.io/graalvm/native-image:22 AS builder
                                    WORKDIR /app
                                    
                                    COPY . .
                                    RUN mvn clean package -DskipTests
                                    
                                    # 构建原生镜像
                                    RUN native-image -jar target/myapp-1.0.0.jar \
                                        --no-fallback \
                                        --enable-https \
                                        -H:Name=myapp-native
                                    
                                    # 运行阶段
                                    FROM alpine:latest
                                    RUN apk --no-cache add libstdc++
                                    COPY --from=builder /app/myapp-native /app/myapp-native
                                    
                                    EXPOSE 8080
                                    ENTRYPOINT ["/app/myapp-native"]
                                    

                                    八、最佳实践总结

                                    8.1 版本管理

                                    <!-- 统一版本管理 -->
                                    <properties>
                                        <java.version>11</java.version>
                                        <maven.compiler.version>3.8.1</maven.compiler.version>
                                        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                                    </properties>
                                    

                                    8.2 安全考虑

                                    • 使用非root用户运行容器
                                    • 定期更新基础镜像
                                    • 扫描镜像安全漏洞

                                    8.3 性能优化

                                    # 使用轻量级基础镜像
                                    FROM openjdk:11-jre-slim
                                    
                                    # 优化JVM参数
                                    ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
                                    

                                    8.4 CI/CD集成示例

                                    name: Java CI/CD Pipeline
                                    
                                    on:
                                      push:
                                        branches: [ main ]
                                    
                                    jobs:
                                      build:
                                        runs-on: Ubuntu-latest
                                        
                                        steps:
                                        - uses: actions/checkout@v2
                                        
                                        - name: Set up JDK 11
                                          uses: actions/setup-java@v2
                                          with:
                                            java-version: '11'
                                            distribution: 'temurin'
                                            cache: 'maven'
                                        
                                        - name: Build and Test
                                          run: mvn clean package
                                          
                                        - name: Build Docker Image
                                          run: docker build -t myapp:${{ github.sha }} .
                                          
                                        - name: Deploy to Registry
                                          run: |
                                          python  echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
                                            docker push myapp:${{ github.sha }}
                                    

                                    结语

                                    Java项目打包已经从简单的JAR文件发展到现代化的容器化部署。掌握这些打包技术对于Java开发者至关重要。无论是传统的Web应用还是现代的微服务,选择合适的打包方式都能大大提高开发和部署效率。

                                    以上就是Java项目打包从JAR到Docker的全方位指南的详细内容,更多关于Java项目打包从JAR到Docker的资料请关注编程客栈(www.devze.com)其它相关文章!

                                    0

                                    上一篇:

                                    下一篇:

                                    精彩评论

                                    暂无评论...
                                    验证码 换一张
                                    取 消

                                    最新开发

                                    开发排行榜