Explorar o código

第二轮整体测试,代码优化、逻辑完善、bug修复

JustryDeng %!s(int64=5) %!d(string=hai) anos
pai
achega
0d323613b4
Modificáronse 16 ficheiros con 513 adicións e 363 borrados
  1. 10 3
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java
  2. 5 0
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java
  3. 38 27
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AlreadyProtectedLibs_Test.java
  4. 71 22
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Debug_Test.java
  5. 80 25
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ExcludePrefix_Test.java
  6. 28 22
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/FinalName_Test.java
  7. 49 23
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludeLibs_Test.java
  8. 44 23
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludePrefix_Test.java
  9. 4 0
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/MixTest.java
  10. 62 22
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/OriginJarOrWar_Test.java
  11. 0 55
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ProtectedLibTest.java
  12. 0 91
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ReversesTest.java
  13. 63 22
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/SupportFile_Test.java
  14. 59 28
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Tips_Test.java
  15. BIN=BIN
      class-winter-core/src/test/resources/help/mybatis-3.5.1.jar
  16. BIN=BIN
      class-winter-core/src/test/resources/help/spring-boot-2.2.8.RELEASE.jar

+ 10 - 3
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java

@@ -69,12 +69,12 @@ public class Reverses {
                     if (Cache.sealCache == null) {
                         byte[] sealByte = IOUtil.readFileFromWorkbenchRoot(new File(projectPath), Constant.SEAL_FILE);
                         String sealContent = new String(sealByte, StandardCharsets.UTF_8);
-                        Logger.debug(DecryptExecutor.class, "sealContent " + sealContent);
                         if (StrUtil.isBlank(sealContent)) {
                             Logger.error(Reverses.class, "Obtain project seal fail.");
                             // 结束程序
                             System.exit(-1);
                         }
+                        Logger.debug(Reverses.class, "seal of the project is -> " + sealContent);
                         Cache.sealCache = sealContent;
                     }
                     
@@ -82,8 +82,12 @@ public class Reverses {
                     if (DecryptExecutor.checklistContain(projectPath, className) && DecryptExecutor.verifySeal(classfileBuffer)) {
                         //noinspection DuplicatedCode
                         try {
-                            return DecryptExecutor.process(projectPath, null, className, javaagentCmdArgs.getPassword() == null ? null :
+                            Logger.debug(Reverses.class, "Decrypt class[" + className + "] start.");
+                            classfileBuffer = DecryptExecutor.process(projectPath, null, className,
+                                    javaagentCmdArgs.getPassword() == null ? null :
                                     javaagentCmdArgs.getPassword().toCharArray());
+                            Logger.debug(Reverses.class, "Decrypt class[" + className + "] end.");
+                            return classfileBuffer;
                         } catch (Exception e) {
                             if (javaagentCmdArgs.isDebug()) {
                                 Logger.error(Reverses.class, ExceptionUtil.getStackTraceMessage(e));
@@ -102,8 +106,11 @@ public class Reverses {
                         String classWinterInfoDir = DecryptExecutor.getLibDirRelativePath(className);
                         //noinspection DuplicatedCode
                         try {
+                            Logger.debug(Reverses.class, "Decrypt class[" + className + "] start.");
                             // lib中的密码在加密时,都统一处理好了,这里直接传null
-                            return DecryptExecutor.process(projectPath, classWinterInfoDir, className, null);
+                            classfileBuffer = DecryptExecutor.process(projectPath, classWinterInfoDir, className, null);
+                            Logger.debug(Reverses.class, "Decrypt class[" + className + "] end.");
+                            return classfileBuffer;
                         } catch (Exception e) {
                             if (javaagentCmdArgs.isDebug()) {
                                 Logger.error(Reverses.class, ExceptionUtil.getStackTraceMessage(e));

+ 5 - 0
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java

@@ -191,6 +191,9 @@ public class EncryptExecutor {
      * @return  加密处理后生成的jar/war文件的位置
      */
     public String process() {
+        // pre-step
+        Logger.debug(EncryptExecutor.class, "Generate seal -> " + Constant.SEAL);
+        
         // step0. 解压jar到jarRootDir下
         JarUtil.unJarWar(originJarOrWar, targetRootDir);
         
@@ -625,9 +628,11 @@ public class EncryptExecutor {
         classFiles.forEach(classFile -> {
             String className = JavassistUtil.resolveClassName(classFile.getAbsolutePath(), true);
             byte[] bytes = IOUtil.toBytes(classFile);
+            Logger.debug(EncryptExecutor.class, "Encrypt class[" + className + "] start.");
             bytes = EncryptUtil.encrypt(bytes, obtainPassword());
             // 将加密后的内容存储到指定位置下
             IOUtil.toFile(bytes, new File(savaDir, className), true);
+            Logger.debug(EncryptExecutor.class, "Encrypt class[" + className + "] end.");
             encryptClasses.add(className);
         });
         return encryptClasses;

+ 38 - 27
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AlreadyProtectedLibs_Test.java

@@ -65,20 +65,26 @@ public class AlreadyProtectedLibs_Test {
      */
     private static void test1() {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-no-pwd.jar")
-                // includePrefix字段是必填的,但是如果我们项目(my-project-with-encrypted-lib-no-pwd.jar)本身不需要进行混淆的话,
-                // 那么这里值随便填一个使其不匹配当前项目的包前缀即可
-                .includePrefix("non-exist")
-                .alreadyProtectedLibs("encrypted-lib-no-pwd-1.0.0.jar")
-                .debug(true)
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-no-pwd.jar";
+        String includePrefix = "non-exist";
+        String alreadyProtectedLibs = "encrypted-lib-no-pwd-1.0.0.jar";
+        
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " alreadyProtectedLibs=" + alreadyProtectedLibs
+                + " debug=" + true
+                ;
+        
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+        
     
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
+        
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+        
+        // 解密(模拟启动加密后的jar包)
         // String javaagentArgs = "";
         String javaagentArgs = "=debug=true";
         // String javaagentArgs = "=debug=true,password=xxx";
@@ -105,21 +111,26 @@ public class AlreadyProtectedLibs_Test {
      */
     private static void test2() {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-have-pwd.jar")
-                // includePrefix字段是必填的,但是我们项目(my-project-with-encrypted-lib-no-pwd.jar)本身是没有混淆的,
-                // 只是其中的lib(encrypted-lib-no-pwd-1.0.0.jar)混淆了,我们项目是没必要进行解密的,所以这里值随便填什么都可以的
-                .includePrefix("non-exist")
-                // 多个之间使用逗号隔开,形如 xxx1.jar:password1,xxx2.jar:password2
-                .alreadyProtectedLibs("encrypted-lib-have-pwd-1.0.0.jar:qwer123~")
-                .debug(true)
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "my-project-with-encrypted-lib-have-pwd.jar";
+        String includePrefix = "non-exist";
+        String alreadyProtectedLibs = "encrypted-lib-have-pwd-1.0.0.jar:qwer123~";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " alreadyProtectedLibs=" + alreadyProtectedLibs
+                + " debug=" + true
+                ;
+    
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
     
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
+        // 解密(模拟启动加密后的jar包)
         // String javaagentArgs = "";
         String javaagentArgs = "=debug=true";
         // String javaagentArgs = "=debug=true,password=xxx";

+ 71 - 22
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Debug_Test.java

@@ -9,7 +9,10 @@ import winter.com.ideaaedi.classwinter.util.PathUtil;
 import java.util.concurrent.TimeUnit;
 
 /**
- * 测试originJarOrWar
+ * 测试debug
+ * <p>
+ *     debug: 是否开启debug模式
+ * </p>
  *
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
@@ -17,28 +20,74 @@ import java.util.concurrent.TimeUnit;
 public class Debug_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(Debug_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
-        
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
+        
+//        test0();
+        test1();
+    
+    }
+    
+    /**
+     * 不开启debug(默认即为不开启)
+     * <p>
+     *     对照{@link Debug_Test#test1()}
+     * </p>
+     */
+    private static void test0() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+        
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                ;
+        
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+        
+        
+        
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+        
+        // 解密(模拟启动加密后的jar包)
         String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
+        // String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
+        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
+    }
+    
+    /**
+     * 开启debug
+     * <p>
+     *     对照{@link Debug_Test#test0()}
+     * </p>
+     */
+    private static void test1() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " debug=" + true
+                ;
+        
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+        
+        
+        
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+        
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }

+ 80 - 25
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ExcludePrefix_Test.java

@@ -1,44 +1,99 @@
 package winter.com.ideaaedi.classwinter;
 
 import winter.com.ideaaedi.classwinter.author.JustryDeng;
-import winter.com.ideaaedi.classwinter.executor.EncryptExecutor;
 import winter.com.ideaaedi.classwinter.util.BashUtil;
 import winter.com.ideaaedi.classwinter.util.Constant;
 import winter.com.ideaaedi.classwinter.util.PathUtil;
 
-import java.util.concurrent.TimeUnit;
-
 /**
- * 测试originJarOrWar
- *
+ * 测试excludePrefix
+ * <p>
+ *     excludePrefix: 对includePrefix定位出来的加密范围,进行排除
+ * </p>
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class ExcludePrefix_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(ExcludePrefix_Test.class);
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
+        test0();
+//        test1();
+    }
+    
+    /**
+     * case:
+     *     根据前缀匹配,以com.aspire.ssm.util.AesEncryptDecryptUtil和com.aspire.ssm.util.DbSecurityBeanUtil为前缀的类都会被加密
+     * 观察输入日志:
+     *     2021-06-13 15:54:32 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] start.
+     *     2021-06-13 15:54:34 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] end.
+     *     2021-06-13 15:54:34 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil$NotSupportedEncryptDecryptException] start.
+     *     2021-06-13 15:54:34 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil$NotSupportedEncryptDecryptException] end.
+     *     2021-06-13 15:54:34 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil] start.
+     *     2021-06-13 15:54:34 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil] end.
+     *     可知确实以com.aspire.ssm.util.AesEncryptDecryptUtil和com.aspire.ssm.util.DbSecurityBeanUtil为前缀的类都被加密了
+     */
+    public static void test0() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com.aspire.ssm.util.AesEncryptDecryptUtil,com.aspire.ssm.util.DbSecurityBeanUtil";
+        
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " debug=" + true
+                ;
         
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
         
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
+        
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+        
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
+        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
+    }
+    
+    /**
+     * case:
+     *     根据前缀匹配,本来以com.aspire.ssm.util.AesEncryptDecryptUtil和com.aspire.ssm.util.DbSecurityBeanUtil为前缀的类都会被加密的,
+     *      但是excludePrefix对以com.aspire.ssm.util.DbSecurityBeanUtil为前缀的类进行了排除,所以最
+     *      终只会有以com.aspire.ssm.util.AesEncryptDecryptUtil为前缀的类会被加密
+     * 观察输入日志:
+     *     2021-06-13 15:51:57 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] start.
+     *     2021-06-13 15:52:01 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] end.
+     *     可知确实只有AesEncryptDecryptUtil被加密了,DbSecurityBeanUtil没有被加密
+     */
+    public static void test1() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com.aspire.ssm.util.AesEncryptDecryptUtil,com.aspire.ssm.util.DbSecurityBeanUtil";
+        String excludePrefix = "com.aspire.ssm.util.DbSecurityBeanUtil";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " excludePrefix=" + excludePrefix
+                + " debug=" + true
+                ;
+    
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }

+ 28 - 22
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/FinalName_Test.java

@@ -9,36 +9,42 @@ import winter.com.ideaaedi.classwinter.util.PathUtil;
 import java.util.concurrent.TimeUnit;
 
 /**
- * 测试originJarOrWar
- *
+ * 测试finalName
+ * <p>
+ *     finalName: 指定混淆后生成的jar包(,若与原jar/war包同名,则会覆盖原jar/war包)
+ * </p>
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class FinalName_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(FinalName_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
         
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+        String finalName = "YiYaKaKa";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " finalName=" + finalName
+                ;
+    
+        args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+    
+        String encryptedJar = projectRootDir + finalName + ".jar";
+    
+        // 解密(模拟启动加密后的jar包)
         String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
+        // String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }

+ 49 - 23
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludeLibs_Test.java

@@ -9,36 +9,62 @@ import winter.com.ideaaedi.classwinter.util.PathUtil;
 import java.util.concurrent.TimeUnit;
 
 /**
- * 测试originJarOrWar
- *
+ * 测试includeLibs
+ * <p>
+ *     includeLibs: 默认的,我们的加密范畴为当前项目的class, 而includeLibs和excludePrefix也对在加密范畴内的class才会生效。
+ *                  在某些场景中,我们不仅需要对当前项目的class进行加密,我们还可能需要对项目里依赖的libs(里的某些class)进行加密。
+ *                  那么就可以通过includeLibs来指定libs,将libs也一同拉入加密范畴。
+ *            提示: 对于依赖传递的场景,我们在使用includeLibs时,直接平铺开就行。比如说,你的项目的依赖关系是: your-project -> a.jar -> b.jar -> c.jar,
+ *                  除了项目本身外,你想要同时对a和c加密的话, 直接这样写includeLibs=a.jar,c.jar即可, 不用考虑依赖传递的问题
+ * </p>
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class IncludeLibs_Test {
     
+    /**
+     * 观察日志,你会发现日志记录:
+     * 2021-06-13 16:13:57 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.google.common.xml.package-info] start.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.google.common.xml.package-info] end.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.google.common.xml.XmlEscapers] start.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.google.common.xml.XmlEscapers] end.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource] start.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource] end.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[org.springframework.aop.target.dynamic.BeanFactoryRefreshableTargetSource] start.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[org.springframework.aop.target.dynamic.BeanFactoryRefreshableTargetSource] end.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[org.springframework.aop.target.dynamic.Refreshable] start.
+     * 2021-06-13 16:13:59 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[orgspringframework.aop.target.dynamic.Refreshable] end.
+     *
+     * 直接解压反编译加密出来的包,然后再反编译里面的spring-aop-5.1.8.RELEASE.jar和guava-28.2-jre.jar,观察对应的类,就会发现该类确实是被加密了的。
+     */
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(IncludeLibs_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
-        
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
+    
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "org.springframework.aop.target.dynamic,com.google.common.xml";
+        String includeLibs = "spring-aop-5.1.8.RELEASE.jar,guava-28.2-jre.jar";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " includeLibs=" + includeLibs
+                + " debug=" + true
+                ;
+    
+        args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密(模拟启动加密后的jar包)
         String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
+        // String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }

+ 44 - 23
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludePrefix_Test.java

@@ -9,36 +9,57 @@ import winter.com.ideaaedi.classwinter.util.PathUtil;
 import java.util.concurrent.TimeUnit;
 
 /**
- * 测试originJarOrWar
+ * 测试includePrefix
+ * <p>
+ *     includePrefix: 根据前缀匹配,以com.aspire.ssm.util.AesEncryptDecryptUtil和com.aspire.ssm.util.DbSecurityBeanUtil为前缀的类都会被加密
+ * </p>
  *
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class IncludePrefix_Test {
     
+    /**
+     * 观察日志,你会发现日志记录:
+     *     2021-06-13 16:21:15 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.AesEncryptDecryptUtil] end.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.ClazzDumpCustomAgent] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.ClazzDumpCustomAgent] end.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil$NotSupportedEncryptDecryptException] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil$NotSupportedEncryptDecryptException] end.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.DbSecurityBeanUtil] end.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.EmployeePO$EmployeePOBuilder] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.EmployeePO$EmployeePOBuilder] end.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.EmployeePO] start.
+     *     2021-06-13 16:21:18 [DEBUG] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Encrypt class[com.aspire.ssm.util.EmployeePO] end.
+     *
+     * 直接解压反编译加密出来的包,观察com.aspire.ssm.util包下的类,就会发现确实是被加密了的。
+     */
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(IncludePrefix_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
-        
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
-        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
+        // 杀下进程(以保证端口没有被占用)
         BashUtil.killProcessByPorts("8080");
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com.aspire.ssm.util";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " debug=" + true
+                ;
+    
+        args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
+        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
     }
 }

+ 4 - 0
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/MixTest.java

@@ -2,6 +2,7 @@ package winter.com.ideaaedi.classwinter;
 
 import winter.com.ideaaedi.classwinter.author.JustryDeng;
 import winter.com.ideaaedi.classwinter.executor.EncryptExecutor;
+import winter.com.ideaaedi.classwinter.util.BashUtil;
 import winter.com.ideaaedi.classwinter.util.Logger;
 import winter.com.ideaaedi.classwinter.util.PathUtil;
 
@@ -21,6 +22,9 @@ public class MixTest {
      * 加密测试
      */
     public static String encryptTest() {
+    
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
         String projectRootDir = PathUtil.getProjectRootDir(MixTest.class);
         
         EncryptExecutor encryptExecutor = EncryptExecutor.builder()

+ 62 - 22
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/OriginJarOrWar_Test.java

@@ -10,35 +10,75 @@ import java.util.concurrent.TimeUnit;
 
 /**
  * 测试originJarOrWar
- *
+ * <p>
+ *     originJarOrWar: 指定要加密的jar/war
+ * </p>
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class OriginJarOrWar_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(OriginJarOrWar_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
         
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
+        test0();
+//        test1();
+    }
+    
+    /**
+     * 测试当jar/war不存在时
+     */
+    private static void test0() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "non-exist.jar";
+        String includePrefix = "com.aspire.ssm.util";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " debug=" + true
+                ;
+    
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
+        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
+    }
+    
+    /**
+     * 正常测试
+     */
+    private static void test1() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com.aspire.ssm.util";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " debug=" + true
+                ;
+    
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密(模拟启动加密后的jar包)
+        // String javaagentArgs = "";
+        String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
         BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
     }
 }

+ 0 - 55
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ProtectedLibTest.java

@@ -1,55 +0,0 @@
-package winter.com.ideaaedi.classwinter;
-
-import winter.com.ideaaedi.classwinter.author.JustryDeng;
-import winter.com.ideaaedi.classwinter.executor.EncryptExecutor;
-import winter.com.ideaaedi.classwinter.util.Constant;
-import winter.com.ideaaedi.classwinter.util.PathUtil;
-
-/**
- * (non-javadoc)
- *
- * @author {@link JustryDeng}
- * @since 2021/6/5 16:40:06
- */
-public class ProtectedLibTest {
-    
-    public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(MixTest.class);
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-//                .originJarOrWar(projectRootDir + "my-project-with-encrypted-lib-no-pwd.jar")
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "my-project-with-encrypted-lib-have-pwd.jar")
-                
-                .includePrefix("non-exist")
-        
-                // (可选)-> 指明当前项依赖来的lib中,有哪些lib是本身就已经是被class-winter混淆了的
-                //  格式形如 xxx.jar:password, 多个之间使用逗号分割, 如果当初对该lib进行混淆时没有主动指定密码,那么可以不写
-//                .alreadyProtectedLibs("encrypted-lib-no-pwd-1.0.0.jar")
-                .alreadyProtectedLibs("encrypted-lib-have-pwd-1.0.0.jar:qwer12~")
-                //.alreadyProtectedLibs("aa.jar,bb.jar:pwd123,cc.jar:")
-                
-                .debug(true)
-                .build();
-        
-        String encryptedJar = encryptExecutor.process();
-    
-        System.out.println(encryptedJar);
-//        /// - 不使用javaagent, 直接启动 - 测试
-//        /*
-//         * encryptedJar本身的代码是没有被混淆的,不过其依赖的lib [encrypted-lib-no-pwd-1.0.0.jar]被混淆了
-//         */
-//        BashUtil.runCmdAndPrint(String.format("java -jar %s",  encryptedJar));
-
-//        /// - 密码不正确 - 测试
-//        // 使用javaagent运行加密后的jar,测试
-//        String javaagentArgs = "";
-//        //String javaagentArgs = "=debug=true,password=xxx";
-//        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-//
-//        try {
-//            TimeUnit.SECONDS.sleep(3);
-//        } catch (InterruptedException e) {
-//            // ignore
-//        }
-//        BashUtil.killProcessByPorts("8080");
-    }
-}

+ 0 - 91
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ReversesTest.java

@@ -1,91 +0,0 @@
-package winter.com.ideaaedi.classwinter;
-
-import winter.com.ideaaedi.classwinter.author.JustryDeng;
-import winter.com.ideaaedi.classwinter.util.BashUtil;
-
-import java.io.File;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 正向加密
- *
- * <p>
- *     ********** 启动加密后的jar包 **********
- *     java -javaagent:xxx.jar -jar xxx.jar
- *     如果需要传参,下面两种方式都可以
- *     java -javaagent:xxx.jar=k1=v1,k2=v2 -jar xxx.jar
- *     java -javaagent:xxx.jar="k1=v1,k2=v2" -jar xxx.jar
- * </p>
- *
- *
- * <p>
- * ********** 启动加密后的war包 **********
- * for linux,
- *     方式一: 在tomcat/bin目录下创建setenv.sh文件,并写上 set JAVA_OPTS="-javaagent:/xxx.jar=k1=v1,k2=v2"
- *     方式二: 编辑tomcat/bin/catalina.sh文件,在内容的第一行加上
- *            set CATALINA_OPTS="-javaagent:D:/xxx.jar=k1=v1,k2=v2"
- *
- * for windows,
- *     方式一: 在tomcat/bin目录下创建setenv.bat文件,并写上 set JAVA_OPTS="-javaagent:D:/xxx.jar=k1=v1,k2=v2"
- *     方式二: 编辑tomcat/bin/catalina.bat文件,在内容的第一行(即:@echo off后面的第一行)加上
- *            set CATALINA_OPTS="-javaagent:D:/xxx.jar=k1=v1,k2=v2"
- *
- * 注: 对于方式二,其实不一定非要加在第一行的。
- *
- * 注: 其中,xxx.jar是一个agent jar, 首先class-winter-core本身是一个代理jar;其次,class-winter在做加密时,
- *          也同时把class-winter-core里面的相关代理类拷贝到了加密后的jar中,所以加密后的jar也属于代理jar。
- *     所以,这里 xxx.jar可以是 class-winter-core.jar, 也可以是 your-project-encrypted.jar
- *
- * 注: 启动tomcat时,除了在tomcat/conf/server.xml中配置项目基本信息(不论你使用不使用代理,这个都是要配置的)外,记得使用tomcat/bin/下的startup.sh或startup
- * .bat进行启动tomcat。
- * </p>
- *
- *
- * @author {@link JustryDeng}
- * @since 2021/5/6 23:25:24
- */
-public class ReversesTest {
-    
-    /**
-     * 入口
-     * java -javaagent:/tmp/boot-jar-encrypted.jar -jar /tmp/boot-jar-encrypted.jar
-     * java -javaagent:/tmp/boot-jar-encrypted.jar=debug=true,password=qwer123~ -jar /tmp/boot-jar-encrypted.jar
-     */
-    public static void main(String[] args) {
-        // 先生成加密后的jar
-        String encryptedJar = MixTest.encryptTest();
-        encryptedJar = new File(encryptedJar).getAbsolutePath();
-
-        /// - 解密正常 - 测试
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "=debug=true,password=qwer123~";
-        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-        // 提示:正常启动后,jar包正常运行,那么这个cmd拉起的进程一直不会结束,需要主动停止下这个main方法来试图杀死拉起的进程(有时,由于权限
-        //      等原因,即便停止main方法后,其拉起的进程也没有被kill掉,这时就需要用其它的方式来杀进程了)
-
-    
-//        /// - 不使用javaagent,直接启动 - 测试
-//        //
-//        BashUtil.runCmdAndPrint(String.format("java -jar %s", encryptedJar));
-        
-        
-//        /// - 加密时,使用了密码, 解密时不输入密码 - 测试
-//        // 使用javaagent运行加密后的jar,测试
-//        String javaagentArgs = "";
-//        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-        
-//        /// - 密码不正确 - 测试
-//        // 使用javaagent运行加密后的jar,测试
-//        String javaagentArgs = "=password=xxx";
-//        //String javaagentArgs = "=debug=true,password=xxx";
-//        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-    
-    
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        BashUtil.killProcessByPorts("8080");
-    }
-}

+ 63 - 22
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/SupportFile_Test.java

@@ -9,7 +9,15 @@ import winter.com.ideaaedi.classwinter.util.PathUtil;
 import java.util.concurrent.TimeUnit;
 
 /**
- * 测试originJarOrWar
+ * 测试supportFile
+ * <p>
+ *     supportFile:在加密某些类时,由于找不到该类中依赖的其它的类,会导致加密失败。此时,可通过supportFile指定一个jar文件(或者指定一个文件夹)。
+ *                  这个jar文件(这个文件夹及其子孙文件夹下面的所有jar文件)都会被作为一个辅助,来进行加密,这样一来,就不会因为找不到类而导致加密失败了。
+ *            提示: 可以放心的是,作为supportFile的jar包,是不会被打进加密后的jar/war的。
+ * </p>
+ * <p>
+ *  注: 某些项目在打jar包时,是没有把其依赖的lib打进jar包中的,所以会出现[找不到该类中依赖的其它的类,导致加密失败]的情况。
+ * </p>
  *
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
@@ -17,28 +25,61 @@ import java.util.concurrent.TimeUnit;
 public class SupportFile_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(SupportFile_Test.class);
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
+    
+//        test0();
+        test1();
+    }
+    
+    /**
+     * 会因为找不到类,而导致混淆失败
+     *
+     * 日志也有相关提示:
+     * 2021-06-13 16:39:12 [ WARN] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Ignore clear-method-body for className [com.aspire.ssm.config.ServletInitializer], Cannot find 'org.springframework.boot.builder.SpringApplicationBuilder'
+     * 2021-06-13 16:39:12 [ WARN] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Ignore clear-method-body for className [com.aspire.ssm.handler.impl.DefaultAesPreHandlerImpl], Cannot find 'org.apache.ibatis.executor.parameter.ParameterHandler'
+     * 2021-06-13 16:39:12 [ WARN] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Ignore clear-method-body for className [com.aspire.ssm.interceptor.CustomizeMybatisPlugin], Cannot find 'org.apache.ibatis.plugin.Invocation'
+     * 2021-06-13 16:39:12 [ WARN] winter.com.ideaaedi.classwinter.executor.EncryptExecutor: Ignore clear-method-body for className [com.aspire.ssm.SsmApplication], Cannot find 'org.springframework.boot.ApplicationArguments'
+     */
+    private static void test0() {
+        String[] args;
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "normal-jar.jar";
+        String includePrefix = "com";
+        String supportFile = "E:\\Maven\\Repository\\org\\springframework\\boot\\spring-boot\\2.2.8.RELEASE\\spring-boot-2.2.8.RELEASE.jar"
+                      + ","
+                      +"";
         
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                ;
         
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
-        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
-        BashUtil.killProcessByPorts("8080");
+        args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    }
+    
+    /**
+     * 混淆成功
+     *
+     * 日志没有warn提示说混淆失败,同时反编译混淆后的jar包进行观察也会发现是成功了的
+     */
+    private static void test1() {
+        String[] args;
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "normal-jar.jar";
+        String includePrefix = "com";
+        String supportFile = projectRootDir + "help";
+        
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " supportFile=" + supportFile
+                ;
+        
+        args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
     }
 }

+ 59 - 28
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Tips_Test.java

@@ -1,44 +1,75 @@
 package winter.com.ideaaedi.classwinter;
 
 import winter.com.ideaaedi.classwinter.author.JustryDeng;
-import winter.com.ideaaedi.classwinter.executor.EncryptExecutor;
 import winter.com.ideaaedi.classwinter.util.BashUtil;
-import winter.com.ideaaedi.classwinter.util.Constant;
 import winter.com.ideaaedi.classwinter.util.PathUtil;
 
-import java.util.concurrent.TimeUnit;
-
 /**
- * 测试originJarOrWar
- *
+ * 测试tips
+ * <p>
+ *     tips:主动指定提示信息。
+ *     注: tips默认值为ERROR !!!!!!!!!!! Jar(or War) has been protected by class-winter. Please use javaagent re-start project. !!!!!!!!!!!。
+ *     注: 当用户没解密,而直接使用混淆后的代码时,就会报错(给出此tips),同时退出程序。
+ * </p>
  * @author {@link JustryDeng}
  * @since 2021/6/12 14:34:45
  */
 public class Tips_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(Tips_Test.class);
-        
-        // 加密
-        EncryptExecutor encryptExecutor = EncryptExecutor.builder()
-                .originJarOrWar(projectRootDir + Constant.LINUX_FILE_SEPARATOR + "boot-jar.jar")
-                .includePrefix("non-exist")
-                .build();
-        String encryptedJar = encryptExecutor.process();
-        System.out.println(encryptedJar);
-        
-        // (解密)启动
-        // 使用javaagent运行加密后的jar,测试
-        String javaagentArgs = "";
-        //String javaagentArgs = "=debug=true,password=xxx";
-        BashUtil.runCmdAndPrint(String.format("java -javaagent:%s%s -jar %s", encryptedJar, javaagentArgs, encryptedJar));
-
-        try {
-            TimeUnit.SECONDS.sleep(3);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
+        // 杀下进程(以保证端口没有被占用)
         BashUtil.killProcessByPorts("8080");
+//        test0();
+        test1();
+    }
+    
+    /**
+     * 默认提示
+     */
+    public static void test0() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+    
+        String startBat = "java -jar class-winter-core.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                ;
+    
+        String[] args = startBat.replace("java -jar class-winter-core.jar" , "").trim().split(" ");
+        Forward.main(args);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 直接使用混淆后的jar
+        BashUtil.runCmdAndPrint(String.format("java -jar %s", encryptedJar));
+    }
+    
+    /**
+     * 指定提示
+     */
+    public static void test1() {
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        // 加密(模拟命令行输入对jar包进行加密)
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+        String tips = "[潘嘎之交] 潘: 你别怪潘叔说话比较直白, 网络上的东西都是虚拟的, 你把握不住, 孩子! 因为这里的水很深...";
+    
+        // 如果tips值由一些特殊字符(如空格等)的话,可以用windows双引号(linux单引号)引起来。
+        // java -jar class-winter-core-1.0.0.jar originJarOrWar=/boot-jar.jar includePrefix=com tips="[潘嘎之交] 潘: 你别怪潘叔说话比较直白, 网络上的东西都是虚拟的, 你把握不住, 孩子! 因为这里的水很深..."
+        String[] args = {
+                "originJarOrWar=" + originJarOrWar,
+                "includePrefix=" + includePrefix,
+                "tips=" + tips
+        };
+        Forward.main(args);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 直接使用混淆后的jar
+        BashUtil.runCmdAndPrint(String.format("java -jar %s", encryptedJar));
     }
 }

BIN=BIN
class-winter-core/src/test/resources/help/mybatis-3.5.1.jar


BIN=BIN
class-winter-core/src/test/resources/help/spring-boot-2.2.8.RELEASE.jar