Parcourir la source

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

JustryDeng il y a 5 ans
Parent
commit
e1383b8bf1

+ 6 - 24
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java

@@ -410,28 +410,6 @@ public class EncryptExecutor {
             IOUtil.writeContentToFile(encryptedPassword, new File(dirAbsolutePathForLib, Constant.PWD_WINTER_SIMPLE_NAME));
             // 由于这里已经处理了,将所有lib的密码(不论当初加密lib时密码是用户主动输入的还是系统自动产生的),都当做系统自动产生的进行录入,所以这里写死为false
             IOUtil.writeContentToFile("false", new File(dirAbsolutePathForLib, Constant.USER_IF_INPUT_PWD_SIMPLE_NAME));
-    
-            // 擦除MANIFEST.MF中的Premain-Class信息, 如果有的话(步骤:判断是否需要擦除 => 解压lib => 擦除 => 删除原lib => 再压缩得到擦除后的lib => 删除临时目录)
-            byte[] jarManifestFileByte = IOUtil.readFileFromWorkbenchRoot(lib, Constant.MANIFEST_FILE);
-            if (jarManifestFileByte != null) {
-                String content = new String(jarManifestFileByte, StandardCharsets.UTF_8);
-                String agentPremain = "Premain-Class: " + Reverses.class.getName();
-                if (content.contains(agentPremain)) {
-                    content = content.replace(agentPremain, "");
-                    String libAbsolutePath = lib.getAbsolutePath();
-                    String tmpTargetDir = libAbsolutePath.substring(0, libAbsolutePath.length() - 4) + Constant.TMP_DIR_SUFFIX;
-                    JarUtil.unJarWar(libAbsolutePath, tmpTargetDir);
-                    IOUtil.writeContentToFile(content, new File(tmpTargetDir, Constant.MANIFEST_FILE));
-                    // 删除原lib
-                    IOUtil.delete(lib);
-                    // 再生成lib
-                    JarUtil.doJarWar(tmpTargetDir, libAbsolutePath);
-                    // 删除临时目录
-                    IOUtil.delete(new File(tmpTargetDir));
-                }
-
-            }
-
         });
         
         // 校验 - 当多个lib之间,发生加密类冲突时,快速失败
@@ -554,10 +532,14 @@ public class EncryptExecutor {
         
         // 把javaagent信息加入到MANIFEST.MF
         File manifest = new File(this.targetRootDir, "META-INF/MANIFEST.MF");
-        String preMain = "Premain-Class: " + Reverses.class.getName();
+        String preMain = Constant.PREMAIN_CLASS + Reverses.class.getName();
         String[] origin = {};
         if (manifest.exists()) {
-            origin = IOUtil.readContentFromFile(manifest).split(System.lineSeparator());
+            String originContent = IOUtil.readContentFromFile(manifest);
+            if (!StrUtil.isBlank(originContent) && originContent.contains(Constant.PREMAIN_CLASS)) {
+                throw new ClassWinterException(this.originJarOrWar + " already exist Premain-Class at META-INF/MANIFEST.MF");
+            }
+            origin = originContent.split(System.lineSeparator());
         }
         // 在原来的启动函数行后面,插入pre-main指令
         String str = StrUtil.insertStrAfterLine(origin, preMain, "Main-Class:");

+ 5 - 0
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Constant.java

@@ -177,4 +177,9 @@ public interface Constant {
      * artifactId
      */
     String ARTIFACT_ID = "class-winter-maven-plugin";
+    
+    /**
+     * PREMAIN_CLASS
+     */
+    String PREMAIN_CLASS = "Premain-Class: ";
 }

+ 91 - 4
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AlreadyProtectedLibs_Test.java

@@ -62,8 +62,33 @@ import java.util.concurrent.TimeUnit;
 public class AlreadyProtectedLibs_Test {
     
     public static void main(String[] args) {
-        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    TimeUnit.SECONDS.sleep(3);
+                } catch (InterruptedException e) {
+                    // ignore
+                }
+                // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
+                BashUtil.killProcessByPorts("8080");
+            }
+        }));
         
+//        test0();
+        test1();
+//        test2();
+    }
+    
+    /**
+     * 场景:
+     *    项目my-project-with-encrypted-lib-no-pwd.jar中的lib包
+     *    encrypted-lib-no-pwd-1.0.0.jar本身就是被class-winter以自动生成的密码加密过了的
+     * 测试期望结果:
+     *    不用代理,直接(java -jar)启动jar包,会失败
+     */
+    private static void test0() {
+        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")
@@ -74,13 +99,75 @@ public class AlreadyProtectedLibs_Test {
                 .build();
         String encryptedJar = encryptExecutor.process();
         System.out.println(encryptedJar);
-        
+    
+        // 启动
+        BashUtil.runCmdAndPrint(String.format("java -jar %s", encryptedJar));
+
+    }
+    
+    /**
+     * 场景:
+     *    项目my-project-with-encrypted-lib-no-pwd.jar中的lib包
+     *    encrypted-lib-no-pwd-1.0.0.jar本身就是被class-winter以自动生成的密码加密过了的
+     * 测试期望结果:
+     *    正常启动项目my-project-with-encrypted-lib-no-pwd.jar,并
+     *    正常使用encrypted-lib-no-pwd-1.0.0.jar中的功能
+     */
+    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)本身是没有混淆的,
+                // 只是其中的lib(encrypted-lib-no-pwd-1.0.0.jar)混淆了,我们项目是没必要进行解密的,所以这里值随便填什么都可以的
+                .includePrefix("non-exist")
+                .alreadyProtectedLibs("encrypted-lib-no-pwd-1.0.0.jar")
+                .build();
+        String encryptedJar = encryptExecutor.process();
+        System.out.println(encryptedJar);
+    
         // (解密)启动
         // 使用javaagent运行加密后的jar,测试
         String javaagentArgs = "";
-//        String javaagentArgs = "=debug=true,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
+        }
+        // 杀下进程(以防下一个测试方法启动jar时因为端口被占用启动不起来)
+        BashUtil.killProcessByPorts("8080");
+    }
+    
+    /**
+     * 场景:
+     *    项目my-project-with-encrypted-lib-no-pwd.jar中的lib包
+     *    encrypted-lib-no-pwd-1.0.0.jar本身就是被class-winter以用户主动指定的密码加密过了的
+     * 测试期望结果:
+     *    正常启动项目my-project-with-encrypted-lib-no-pwd.jar,并
+     *    正常使用encrypted-lib-no-pwd-1.0.0.jar中的功能
+     */
+    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-no-pwd.jar")
+                // includePrefix字段是必填的,但是我们项目(my-project-with-encrypted-lib-no-pwd.jar)本身是没有混淆的,
+                // 只是其中的lib(encrypted-lib-no-pwd-1.0.0.jar)混淆了,我们项目是没必要进行解密的,所以这里值随便填什么都可以的
+                .includePrefix("non-exist")
+                .alreadyProtectedLibs("my-project-with-encrypted-lib-have-pwd.jar:qwer123~")
+                .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) {

BIN
class-winter-core/src/test/resources/my-project-with-encrypted-lib-have-pwd.jar


BIN
class-winter-core/src/test/resources/my-project-with-encrypted-lib-have-pwd.war


BIN
class-winter-core/src/test/resources/my-project-with-encrypted-lib-no-pwd.jar


BIN
class-winter-core/src/test/resources/my-project-with-encrypted-lib-no-pwd.war