Gradle 使用shadow生成可运行 jar 包

Nov 20, 2018 阅读(14121)

标签: Gradle Java

使用Java 开发客户端程序,开发完成最终交付使用的是可执行的程序,以此需要用到打包,在此记录使用 Gradle shadow 打可执行jar包,build.gradle 如下:

buildscript {
    repositories {
        jcenter()
        maven { url "https://plugins.gradle.org/m2/" }
    }

    dependencies {
        classpath "com.github.jengelman.gradle.plugins:shadow:2.0.4"
    }
}

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: "com.github.johnrengelman.shadow"

group 'cn.xuexiyuan'
version '1.1'
sourceCompatibility = 1.7
targetCompatibility = 1.7
tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

repositories {
    mavenLocal()
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'https://repo.spring.io/libs-snapshot/' }
}

dependencies {
    compile group: 'log4j', name: 'log4j', version: '1.2.17'
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.2.3'
    compile group: 'com.alibaba', name: 'fastjson', version: '1.2.41'
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'
    compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.3.0'
    compile group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.2.3'
    compile group: 'javax', name: 'javaee-api', version: '7.0'
    compile group: 'org.slf4j', name: 'slf4j-nop', version: '1.7.21'
    compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.39'
    compile group: 'commons-net', name: 'commons-net', version: '3.6'
    compile group: 'org.apache.tomcat', name: 'tomcat-websocket', version: '8.0.18'
    compile group: 'com.oracle', name: 'ojdbc', version: '7.0'
    compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.4.2'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

// 构建可执行 jar 包,运行依赖jar内容会直接打到 jar 里面
shadowJar {
    // 生成包的命名规则: baseName-version-classifier.jar
    classifier = null
    manifest {
        attributes(
                'Main-Class': 'cn.xuexiyuan.client.Main'
        )
    }
    
    // 排除配置文件
    exclude('system.properties')
    exclude('log4j.properties')
    
    // 打包时排除指定的 jar 包
    dependencies {
        exclude(dependency('org.mongodb:mongo-java-driver:3.3.0'))
    }
    
    // 将 build.gradle 打入到 jar 中, 方便查看依赖包版本
    from("./"){
        include 'build.gradle'
    }
}


//  构建可执行 jar 包并上传至 maven
uploadShadow {
    repositories {
        mavenDeployer {
            //上传资源到Maven私服
            repository(url: "http://maven.xuexiyuan.cn:8081/repository/maven-releases/") {
                authentication(userName:"admin", password:"passwd")
            }
            pom.version ="$project.version"
            pom.artifactId ="$project.name"
            pom.groupId ="$project.group"
        }
    }
}

执行 gradle uploadShadow 构建可运行的 jar 并上传到maven 上去。  gradle shadowJar 构建可运行的 jar,这种方式打的jar 包会将所依赖的 jar 的内容都打包进去,结构如下所示:

 1542715731437.png

生成包的命名规则: baseName-version-classifier.jar,如果在shadowJar 中没有指定 classifier = null,则最终打的 jar 包名称,就像上面的xuexiyuan-client-1.1-all.jar 一样,这里的classifier 就是 -all。

 

尝试过将依赖jar不通过解压内容方式直接打到jar中,而且期望依赖的 jar 以*.jar 的形式存在在最终可运行的jar中(就像Eclipse Export 将依赖的jar 载入的方式一样),但是不管怎么尝试的配置Main-Class总是加载不到依赖的Class 错误。


用户名密码敏感信息过滤

程序打jar时将 build.gradle 也打进去啦,maven 的用户名、密码都在 build.gradle 中,处于安全性考虑应该将密码过滤掉。解决方式在 build.gradle 同级目录下新建 gradle.properties 文件将敏感信息存放在这里(这个文件不打入jar),build.gradle 则直接引用配置文件中的变量。


gradle.properties 配置文件:

maven.username=admin
maven.password=password

build.gradle 中引用方式:

...
//  构建可执行 jar 包并上传至 maven
uploadShadow {
    repositories {
        mavenDeployer {
            //上传资源到Maven私服
            repository(url: "http://maven.xuexiyuan.cn:8081/repository/maven-releases/") {
                authentication(userName:"${maven.username}", password:"${maven.password}")
            }
            pom.version ="$project.version"
            pom.artifactId ="$project.name"
            pom.groupId ="$project.group"
        }
    }
}
...




See:

shadow 官网参考手册

Eclipse 导出java项目成可执行的jar 包 






MongoDB学习园