使用gradle打包jar包

本文介绍如何使用Gradle将Android Library模块打包为Jar文件。文中探讨了三种方法:创建自定义Jar任务、利用libraryVariants配置以及直接复制classes.jar文件。每种方法都有其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STOP MAINTENANCE!(2017-05-25)


最近用android studio来做android开发的IDE,它是使用gradle来构建的,于是开始学习gradle.

现在有一个项目,里面有一个android-library的模块。我想在做release的时候,把这个模块中我写的代码编译并打包成jar包,并且和依赖的jar包拷贝出来,但android studio对android-library的管理是把其与依赖包打包成一个aar的包的,显示这不是我要的,于是便想用gradle来实现。

首先我找到的第一种方法是在模块中的build.gradle增加一个编译jar包的task.代码如下:

task releaseJar(type:Jar) {
    from sourceSet.main.java
    destinationDir = file('build/libs')
}

但是执行的时候,却提示里面的Log类找不到。显示用这种方法只能编译一般的java文件,无法编译用到了android库的源文件。可能是还要在哪里添加依赖吧。


第二种方法是在stackoverflow中找到的,它也确实能打包成jar包。代码如下:

android.libraryVariants.all { variant ->
    def name = variant.buildType.name
    if (name.equals(com.android.builder.BuilderConstants.DEBUG)) {
        return; // skip debug builds
    }
    def task = project.tasks.create "jar${name.capitalize()}, Jar
    task.from variant.javaCompile.destinationDir
    artifacts.add('archives', task)
}

然后执行gradle jarRelease就可以了。

但是它会把我的R.java也编译进去,而且这个文件又很大。我原来的代码编译之后打包才不到13K,加上编译这个文件的话,要28K。


第三种方法就比较取巧了。这是因为gradle在构建的时候,会对这个模块的class文件先打包成classes.jar并放在build/bundles/release。于是我只需要把它拷出来,并重命名就可以了。

于是代码如下:

task releaseJar(type: Copy) {
    from( 'build/bundles/release')
    into( 'build/libs')
    include('classes.jar')
    rename('classes.jar', 'superlog' + VERSION_NAME + '.jar')
}

task releaseLib(type: Copy, dependsOn: releaseJar) {
    into "../../release"
    from 'libs'
    from 'build/libs'
}

其中VERSION_NAME是我定义的一个变量,在gradle.properties文件中。该文件与gradle.build在同级目录。

<think>好的,用户现在想了解如何在不使用Maven和Gradle的情况下打包JAR。之前的对话是关于Maven依赖解析错误的解决方案,用户可能现在遇到了需要手动打包的情况,或者对构建工具不太熟悉,想了解底层原理。 首先,我需要确认用户的需求场景。他们可能是在没有构建工具的环境中工作,或者项目较小,不需要复杂的依赖管理。也有可能用户是初学者,想了解JAR是如何手动创建的,以加深理解。 接下来,我应该回忆手动打包JAR的步骤。通常,这涉及到编译Java文件为.class,然后将类文件和资源文件打包JAR,可能需要处理清单文件(MANIFEST.MF)来指定主类等。同时,用户可能需要知道如何指定依赖的第三方库,这时候需要用到-classpath参数,并可能创建含依赖的可执行JAR。 然后,要考虑用户可能的疑问点,比如如何处理外部依赖,如何运行JAR,以及如何确保目录结构正确。此外,用户可能不知道如何编写清单文件,或者如何将多个依赖JAR合并到自己的JAR中,这时候可能需要解释不同的方法,比如使用jar命令的-C参数切换目录,或者解压依赖后重新打包。 还需要注意,手动打包在依赖较多时会变得复杂,容易出错,这时候应该提醒用户考虑构建工具的优势,但也要尊重用户当前的需求,可能他们有特殊原因必须手动操作。 最后,组织步骤,分点说明,从编译到打包,再到运行,每一步给出示例命令和解释。同时,提醒常见问题,比如类路径错误、主类未找到等,以及解决方法。可能还需要对比不同方法的优缺点,帮助用户做出选择。</think>--- ### **不使用构建工具(Maven/Gradle)手动打包JAR的完整流程** --- #### **一、基础概念** JAR(Java Archive)本质是**带特定目录结构的ZIP文件**,含: - 编译后的`.class`文件 - 资源文件(如`.properties`, `.xml`等) - `META-INF/MANIFEST.MF`(清单文件,定义主类、依赖等) --- ### **二、手动打包步骤** #### **步骤1:编译Java代码** 假设项目结构: ``` src/ com/ example/ Main.java lib/ dependency1.jar dependency2.jar ``` 编译命令: ```bash # 创建输出目录 mkdir -p target/classes # 编译并指定依赖库 javac -d target/classes -cp "lib/*" src/com/example/Main.java ``` #### **步骤2:创建清单文件** 新建`META-INF/MANIFEST.MF`: ``` Manifest-Version: 1.0 Main-Class: com.example.Main Class-Path: lib/dependency1.jar lib/dependency2.jar ``` **注意**: - 最后必须有一个空行 - 路径使用`/`分隔符 - 类路径使用空格分隔 #### **步骤3:打包JAR** ```bash # 进入编译输出目录 cd target/classes # 打包(含清单文件) jar cfm ../myapp.jar ../../META-INF/MANIFEST.MF . # 查看JAR内容 jar tf ../myapp.jar ``` --- ### **三、含依赖的两种方案** #### **方案A:外部依赖(推荐)** ```bash 最终目录结构: myapp.jar lib/ dependency1.jar dependency2.jar ``` 运行时: ```bash java -jar myapp.jar ``` #### **方案B:合并依赖到JAR(FatJAR)** ```bash # 创建临时目录 mkdir merged_lib cd merged_lib # 解压所有依赖 jar xf ../../lib/dependency1.jar jar xf ../../lib/dependency2.jar # 合并编译结果与依赖 cp -r ../../target/classes/* . # 重新打包 jar cfm ../../target/fatjar.jar ../../META-INF/MANIFEST.MF . ``` --- ### **四、关键注意事项** 1. **目录结构要求**: - 类文件必须按`名/子名/ClassName.class`存放 - 示例: ``` com/ example/ Main.class META-INF/ MANIFEST.MF ``` 2. **依赖冲突处理**: - 检查合并后的`META-INF/services`目录 - 处理重复的配置文件和类文件 3. **签名验证**: - 如果依赖库有数字签名,合并后需重新签名 --- ### **五、常见错误处理** | 错误现象 | 原因分析 | 解决方案 | |---------|----------|----------| | `NoClassDefFoundError` | 依赖未正确含 | 检查`Class-Path`声明或合并完整性 | | `找不到主清单属性` | `MANIFEST.MF`未指定主类 | 确认`Main-Class`条目格式正确 | | `java.lang.UnsupportedClassVersionError` | 编译版本与运行环境不符 | 使用`-target`参数指定JDK版本编译 | --- ### **六、进阶技巧** 1. **多模块项目打包**: ```bash # 编译时含多个源码目录 javac -d classes -cp "lib/*" src1/*.java src2/*.java ``` 2. **资源文件处理**: ```bash # 将资源文件复制到classes目录 cp -r src/resources/* target/classes/ ``` 3. **使用Ant脚本**: ```xml <target name="jar"> <jar destfile="build/myapp.jar" basedir="build/classes"> <manifest> <attribute name="Main-Class" value="com.example.Main"/> </manifest> </jar> </target> ``` --- ### **七、手动打包 vs 构建工具** | 对比维度 | 手动打包 | Maven/Gradle | |---------------|-------------------------|-------------------------| | **依赖管理** | 需手动下载配置 | 自动解析传递依赖 | | **构建速度** | 简单项目快 | 复杂项目更高效 | | **标准化** | 易出错 | 统一的项目结构 | | **扩展性** | 修改困难 | 丰富的插件生态系统 | --- 建议仅在小型项目或学习场景使用手动打包,实际开发推荐使用构建工具保证可维护性。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值