写在前面:众所周知,Java程序不管使用maven或者Gradle进行构建,都可以获得一个可运行的jar包,比如现在我写了一个IDEA插件可以实现在IDEA中输入中文的名称之后自动变成是规范的英文类,那么在进行友好的分享时候,如何防止自己的jar依赖被别人翻版,就是本次给大家提供的教学~

IDEA插件获取及介绍

反编译软件介绍

网址链接:https://github.com/skylot/jadx

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java

如何实现反编译

方式一:使用开源的工具

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_02

这里简单以Gradle工程介绍一下在源码中,如何进行配置使用进行打包的混淆

# 需要在这里指明自己需要的打包混淆工具
import proguard.gradle.ProGuardTask

buildscript {
    repositories {
        mavenCentral()
    }
    # 在这里需要说明自己的打包工具版本
    dependencies {
        classpath 'com.guardsquare:proguard-gradle:7.5.0'
    }
}

plugins {
    id 'java'
    id 'org.jetbrains.intellij' version '1.17.3'
}

group = 'com.shuyixiao'
version = '1.0.1'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.apache.groovy:groovy:4.0.14'
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
    implementation("com.google.code.gson:gson:2.11.0")
    implementation("org.jetbrains:annotations:24.1.0")
}

intellij {
    version = '2024.2'
    type = 'IC'
    plugins = ['java', 'Groovy']
}

ext {
    niagara_home = "E:\\ALearn\\IDEA-plugins\\YiXiaoPlugin"  // 这里替换为你实际的项目路径
}

tasks.register('minJar', Jar) {
    archiveClassifier.set('min')
    from sourceSets.main.output
}
# 配置相关的输入输出信息
tasks.register('proguard', ProGuardTask) {
    dependsOn minJar
    doFirst {
        ext {
            injar = tasks.named('minJar').get().archiveFile.get().asFile  // 使用 minJar 任务的输出作为输入
            outJar = file("$buildDir/libs/${rootProject.name}-${version}-proguarded.jar")

            // 动态添加lib目录下的所有JAR文件
            fileTree(dir: 'lib', include: '*.jar').files.each { jarFile ->
                libraryjars(jarFile)
            }

            // 添加Java模块路径
            libraryjars("D:/Program_Files/JDK/jdk-17_windows-x64_bin/jdk-17.0.6/jmods/java.base.jmod")
        }

        injars injar
        outjars outJar
        configuration 'sensetech.pro'
    }
    // 强制任务每次都执行
    outputs.upToDateWhen { false }
}


tasks.named("runIde") {
    jvmArgs = ["-Xmx2g"]
}

tasks {
    patchPluginXml {
        sinceBuild.set("242")
    }
}

test {
    useJUnitPlatform()
}

还需要在源码文件中添加一下sensetech.pro文件

-ignorewarnings  # 忽略警告信息,防止因警告而中断混淆过程

# 允许 com.shuyixiao 包下的所有类进行混淆,但保留类的结构
-keep class com.shuyixiao.** { *; }

# 保留 META-INF 文件夹及其内容不被混淆
-keepdirectories META-INF/

# 优化和混淆规则
-optimizationpasses 500  # 设置优化运行的次数(默认为1),增加次数可能增加混淆效果
-allowaccessmodification  # 允许修改访问修饰符来实现更多优化
-mergeinterfacesaggressively  # 激进地合并接口,减少类的数量
-overloadaggressively  # 激进地重载方法,减少可识别的名称
-dontpreverify  # 不进行预校验,对于一些老版本的 Java 来说,这可以提高兼容性
-printmapping out.map  # 输出映射文件,记录混淆前后的类名和方法名映射关系

# 保留注解
-keepattributes *Annotation*  # 保留所有注解信息,防止因为注解丢失导致的反射或框架使用问题

# 保留 IntelliJ IDEA 插件所需的关键类和接口
-keep class * extends com.intellij.openapi.actionSystem.AnAction {
    public <init>(...);
    public void actionPerformed(...);
}

-keep public class * extends com.intellij.openapi.components.ProjectComponent {
    public <init>(...);
    public void initComponent();
    public void disposeComponent();
    public void getComponentName();
}

-keep class com.intellij.** { *; }
-keep class org.jetbrains.** { *; }
-keep interface org.jetbrains.annotations.* { *; }


# 创建无用代码和调试信息
-dontnote ** # 不输出 ProGuard 的注释信息
-dontwarn **  # 忽略所有警告信息

配置完成之后会在IDEA中的这个位置出现一个打包的标识,双击运行就会出现打包混淆之后的版本。

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_03

混淆之后会在这个位置出现相对应的依赖包

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_04

但是使用上述的混淆方式,有一个很大的问题就是目前我做的尝试,虽然可以实现对jar的混淆,但是反编译之后还是可以看见挺多清晰的类文件信息,没有实现我想要的混淆的效果,而且由于我制作的是IDEA插件,混淆之后安装插件还让本身的功能不好使了,典型的费力不讨好。。。

下面给大家介绍一款完美的打包混淆工具,不仅可以实现对jar文件的混淆,还能让其功能好使,混淆的结果可以说和源码简直是天差地别。话不多说直接上车。

软件的介绍

这里使用的是这个软件,由于是国外的而且收费,比较麻烦的是这个还需要使用公司等商用的邮箱进行注册认证,免费邮箱不好使,获取花钱不说还很麻烦,但是这里有一个好消息是一笑给大家准备好了,关注公众号,搜索:舒一笑的架构笔记。回复:ZKM软件获取。就可以获得软件,需要注意一下我提供的软件需要使用JDK17才能运行。

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_05

实操效果演示

在路径下运行软件

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_06

点击同意之后,遇到Next就点击Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_07

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_08

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_09

添加你需要混淆的jar类的依赖

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_10

添加完成之后继续点击Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_jar_11

选择你需要混淆的依赖,按照顺序操作之后点击Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_jar_12

由于很难一次新将需要的依赖都囊括,这里比较好的一点是如果你在添加依赖时候少添加了后续软件会提示出来进行添加即可。

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_13

点击上一步进行添加

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_jar_14

这里给大家分享一个小技巧就是软件提示你需要进行缺少依赖时候你直接将相关的依赖都选择进来会快很多 选择完成之后就会提示如下图,继续点击Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_jar_15

不用多说一路Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_16

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_17

点击OK

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_反编译_18

继续Next

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_jar_19

选择自己的输出路径

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_20

这里最后点击Exit结束就好了,其实从这边也可以看出原本有相关逻辑的代码这里也变成了abcd

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_21

混淆之后的展示

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_22

如何为你的jar包上保险,防止别人反编译获取代码。Jar混淆全网最详细教学_java_23