Explorar o código

JvmStartCheck功能测试

邓沙利文 %!s(int64=3) %!d(string=hai) anos
pai
achega
c52a9543ba
Modificáronse 27 ficheiros con 215 adicións e 64 borrados
  1. 1 0
      .gitignore
  2. 1 1
      README.md
  3. 1 1
      class-winter-core/pom.xml
  4. 3 0
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Forward.java
  5. 41 6
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java
  6. 4 4
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/DecryptExecutor.java
  7. 62 22
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java
  8. 1 1
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Cache.java
  9. 15 1
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Constant.java
  10. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AllTest.java
  11. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AlreadyProtectedLibs_Test.java
  12. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Debug_Test.java
  13. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ExcludePrefix_Test.java
  14. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/FinalName_Test.java
  15. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludeLibs_Test.java
  16. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludePrefix_Test.java
  17. 52 0
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/JvmStartCheck_Test.java
  18. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/OriginJarOrWar_Test.java
  19. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Password_Test.java
  20. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/SupportFile_Test.java
  21. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Tips_Test.java
  22. 5 5
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/War_Test.java
  23. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Xml_Test.java
  24. BIN=BIN
      class-winter-core/src/test/resources/class-winter-core-2.5.0.jar
  25. 1 1
      class-winter-maven-plugin/pom.xml
  26. 6 0
      class-winter-maven-plugin/src/main/java/winter/com/ideaaedi/classwinter/plugin/ClassWinterPlugin.java
  27. 1 1
      pom.xml

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 *.iml
 .idea
 target
+/class-winter-core/dependency-reduced-pom.xml

+ 1 - 1
README.md

@@ -31,7 +31,7 @@
   <plugin>
       <groupId>com.idea-aedi</groupId>
       <artifactId>class-winter-maven-plugin</artifactId>
-      <version>2.4.0</version>
+      <version>2.5.0</version>
       <!-- 相关配置 -->
       <configuration>
           <!-- <finalName></finalName>-->

+ 1 - 1
class-winter-core/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.idea-aedi</groupId>
         <artifactId>class-winter</artifactId>
-        <version>2.4.0</version>
+        <version>2.5.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 3 - 0
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Forward.java

@@ -35,6 +35,7 @@ public class Forward {
         String alreadyProtectedLibs = parseValueByPrefixFromTail("alreadyProtectedLibs=", args);
         String tips = parseValueByPrefixFromTail("tips=", args);
         String supportFile = parseValueByPrefixFromTail("supportFile=", args);
+        String jvmStartCheck = parseValueByPrefixFromTail("jvmStartCheck=", args);
         String debug = parseValueByPrefixFromTail("debug=", args);
         
         Logger.ENABLE_DEBUG.set(Boolean.parseBoolean(debug));
@@ -50,6 +51,7 @@ public class Forward {
         Logger.debug(Forward.class, "You input arg alreadyProtectedLibs -> " + alreadyProtectedLibs);
         Logger.debug(Forward.class, "You input arg tips -> " + tips);
         Logger.debug(Forward.class, "You input arg supportFile -> " + supportFile);
+        Logger.debug(Forward.class, "You input arg jvmStartCheck -> " + jvmStartCheck);
         Logger.debug(Forward.class, "You input arg debug -> " + debug);
         
         // 构造加密执行器
@@ -66,6 +68,7 @@ public class Forward {
                 .alreadyProtectedLibs(alreadyProtectedLibs)
                 .debug(Boolean.parseBoolean(debug))
                 .supportFile(supportFile)
+                .jvmStartCheck(jvmStartCheck)
                 .tips(tips)
                 .build();
     

+ 41 - 6
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java

@@ -16,9 +16,12 @@ import java.io.File;
 import java.io.IOException;
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.Instrumentation;
+import java.lang.management.ManagementFactory;
 import java.nio.charset.StandardCharsets;
 import java.security.ProtectionDomain;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.zip.ZipFile;
@@ -42,9 +45,11 @@ public class Reverses {
      *            This class provides services needed to instrumentation Java programming language code
      */
     public static void premain(String args, Instrumentation instrumentation) {
+        // javaagent指定的参数
         if (javaagentCmdArgs == null) {
             try {
                 javaagentCmdArgs = JavaagentCmdArgs.parseJavaagentCmdArgs(args);
+                Logger.debug(Reverses.class, "Parse raw javaagent args [" + args + "] to javaagentCmdArgs -> " + javaagentCmdArgs);
             } catch (Exception e) {
                 Logger.error(Reverses.class,  ExceptionUtil.getStackTraceMessage(e));
                 System.exit(-1);
@@ -52,8 +57,6 @@ public class Reverses {
             // 是否启动debug,同步给Logger
             Logger.ENABLE_DEBUG.set(javaagentCmdArgs.isDebug());
         }
-        
-        Logger.debug(Reverses.class, "Parse raw args [" + args + "] to javaagentCmdArgs -> " + javaagentCmdArgs);
     
         final AtomicBoolean firstExec = new AtomicBoolean(false);
     
@@ -90,17 +93,49 @@ public class Reverses {
                         Cache.sealCache = sealContent;
                     }
     
-                    /// ============================================ 处理non-class文件
+                    /// ============================================ 1.校验启动时是否输入了加密时指定的jvm参数   2.处理non-class文件
                     final String inputPwd = javaagentCmdArgs.getPassword();
                     if (firstExec.compareAndSet(false, true)) {
+                        //  1.校验启动时是否输入了加密时指定的jvm参数
+                        try {
+                            byte[] jvmStartCheckBytes = IOUtil.readFileFromWorkbenchRoot(new File(projectPath), Constant.JVM_START_CHECK_FILE);
+                            if (jvmStartCheckBytes == null) {
+                                throw new IllegalStateException("jvmStartCheckBytes should not be null.");
+                            }
+                            String jvmStartCheck = new String(jvmStartCheckBytes, StandardCharsets.UTF_8);
+                            Logger.debug(Reverses.class, "jvmStartCheck is -> " + jvmStartCheck);
+                            if (StrUtil.isBlank(jvmStartCheck)) {
+                                throw new IllegalStateException("jvmStartCheck should not be blank.");
+                            }
+                            if (!Constant.JVM_START_CHECK_NO_ITEM_CONTENT.equals(jvmStartCheck)) {
+                                List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
+                                Logger.debug(Reverses.class, "Parse jvm start args -> " + inputArguments);
+                                Arrays.stream(jvmStartCheck.split(Constant.WHITE_SPACE))
+                                        .filter(str -> !StrUtil.isBlank(str))
+                                        .forEach(jvmItem -> {
+                                            if (!inputArguments.contains(jvmItem)) {
+                                                throw new IllegalArgumentException("Miss jvm start arg -> " + jvmItem);
+                                            }
+                                        });
+                            }
+                        } catch (Exception e) {
+                            Logger.error(Reverses.class, "jvm-start-check fail.");
+                            Logger.error(Reverses.class, ExceptionUtil.getStackTraceMessage(e));
+                            System.exit(-1);
+                            // 上一步System.exit(-1)就退出程序了,照理说是不会走到下面这里的(,不过为了以防万一,这里打出提醒, class-winter失效)
+                            for (int i = 0; i < Constant.TEN; i++) {
+                                Logger.error(Reverses.class, "!!!!!!!!!!! class-winter Invalidation. !!!!!!!!!!!");
+                            }
+                            return null;
+                        }
+                        
+                        //  2.处理non-class文件
                         try {
                             // 解混淆 除了class文件外的其它文件
                             Map<String, Pair<byte[], byte[]>> resultMap =
                                     DecryptExecutor.unMaskNonClassFiles(projectPath, inputPwd == null ? null : inputPwd.toCharArray());
                             Map<String, byte[]> tmpMap = new HashMap<>(16);
-                            resultMap.forEach((k, v) -> {
-                                tmpMap.put(k, v.getLeft());
-                            });
+                            resultMap.forEach((k, v) -> tmpMap.put(k, v.getLeft()));
                             String finalProjectPath = projectPath;
                             Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                                 try {

+ 4 - 4
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/DecryptExecutor.java

@@ -50,17 +50,17 @@ public class DecryptExecutor {
      *            jar/war文件或目录(如: /tmp/, /tmp/abc.jar等)
      * @param classWinterInfoDir
      *            class-winter相关信息的存储目录(如果不指定,则走默认的目录)
-     * @param classLongName
-     *            class全类名(如: com。niantou.winter.core.Abc)
+     * @param filename
+     *            文件名(如: com。niantou.winter.core.Abc)
      * @param password
      *            密码
      * @return  解压后的字节(null-表示classLongName所代表的文件不应该被解密)
      */
-    public static byte[] process(String projectPath, String classWinterInfoDir, String classLongName, char[] password) {
+    public static byte[] process(String projectPath, String classWinterInfoDir, String filename, char[] password) {
         String baseWinterInfoDir = StrUtil.isBlank(classWinterInfoDir) ? Constant.DEFAULT_ENCRYPTED_BASE_SAVE_DIR : classWinterInfoDir;
         classWinterInfoDir = StrUtil.isBlank(classWinterInfoDir) ? Constant.DEFAULT_ENCRYPTED_CLASSES_SAVE_DIR : classWinterInfoDir;
         // 读取文件
-        byte[] bytes = IOUtil.readFileFromWorkbenchRoot(new File(projectPath), classWinterInfoDir + classLongName);
+        byte[] bytes = IOUtil.readFileFromWorkbenchRoot(new File(projectPath), classWinterInfoDir + filename);
         // 检查密码一致性
         boolean userIfInputPwdWhileDecrypt = checkPwdConsistency(projectPath, baseWinterInfoDir, password);
         // 解密

+ 62 - 22
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java

@@ -191,6 +191,11 @@ public class EncryptExecutor {
      */
     private final String supportFile;
     
+    /**
+     * 在启动jar包时,需要进行的jvm输入参数校验
+     */
+    private final Set<String> jvmStartCheckSet;
+    
     /**
      * 要加密的lib jar文件的绝对路径  &  其对应的加密临时目录
      * 如:  /xyz/abc.jar     与 /xyz/abc__temp__
@@ -201,7 +206,7 @@ public class EncryptExecutor {
                             String targetLibDir, String targetClassesDir, String password,
                             Set<String> includeXmlPrefixSet, Set<String> excludeXmlPrefixSet, Set<String> toCleanXmlChildElementNameSet,
                             Set<String> includePrefixSet, Set<String> excludePrefixSet, Set<String> includeLibSet,
-                            Set<Pair<String, String>> alreadyProtectedLibSet, String supportFile) {
+                            Set<Pair<String, String>> alreadyProtectedLibSet, String supportFile, Set<String> jvmStartCheckSet) {
         this.originJarOrWar = originJarOrWar;
         this.originIsJar = originIsJar;
         this.finalName = finalName;
@@ -217,6 +222,7 @@ public class EncryptExecutor {
         this.includeLibSet = includeLibSet;
         this.alreadyProtectedLibSet = alreadyProtectedLibSet;
         this.supportFile = supportFile;
+        this.jvmStartCheckSet = jvmStartCheckSet;
     }
     
     /**
@@ -229,62 +235,66 @@ public class EncryptExecutor {
         Logger.debug(EncryptExecutor.class, "Generate seal -> " + Constant.SEAL);
         
         // step0. 解压jar到jarRootDir下
-        List<String> filePathList = JarUtil.unJarWar(originJarOrWar, targetRootDir);
-        String lastStep = "step12";
+        String lastStep = "step13";
         showProcess("step00", lastStep, "un-jar-war");
+        List<String> filePathList = JarUtil.unJarWar(originJarOrWar, targetRootDir);
     
+        showProcess("step01", lastStep, "clean-xml-files");
         File targetRootDirFile = new File(targetRootDir);
         if (includeXmlPrefixSet != null && includeXmlPrefixSet.size() > 0) {
             cleanXmlFiles(filePathList, targetRootDirFile);
         }
-        showProcess("step01", lastStep, "clean-xml-files");
     
         // step1. jar中的某些lib可能也需要加密,这里先(将那些需要加密的lib)进行解压,(解压到对应的临时目录,以便后面进行加密处理)
-        unLibJar();
         showProcess("step02", lastStep, "un-lib-jar");
+        unLibJar();
         
         // step2. 找到需要加密混淆的class文件
+        showProcess("step03", lastStep, "filter-classes");
         List<File> allFiles = IOUtil.listSubFile(targetRootDirFile, 1);
         List<File> allNeedEncryptedClassFileList = filterClasses(allFiles);
-        showProcess("step03", lastStep, "filter-classes");
         
+        showProcess("step04", lastStep, "encrypt-classes");
         // step3.1. 根据原.class文件,生成加密后的.class文件,并存至Constant.ENCRYPTED_CLASSES_SAVE_DIR
         List<String> allAlreadyEncryptedClassFileList = encryptClasses(allNeedEncryptedClassFileList, new File(targetRootDir,
                 Constant.DEFAULT_ENCRYPTED_CLASSES_SAVE_DIR));
         // step3.2. 生成记录已加密class的全类名的清单文件
         generateChecklistFile(allAlreadyEncryptedClassFileList);
-        showProcess("step04", lastStep, "un-jar-war");
         
         // step4. 记录印章(在解密时,可通过 checklist + 印章 判断一个class是否是被class-winter加密过)
+        showProcess("step05", lastStep, "record-seal");
         generateSealFile();
-        showProcess("step05", lastStep, "encrypt-classes");
 
-        // step5. 混淆原.class文件(即:清空方法体)
+        // step5. 记录sss(在解密时,可通过 checklist + 印章 判断一个class是否是被class-winter加密过)
+        showProcess("step06", lastStep, "record-jvm-start-check-items");
+        generateJvmStartCheckItems();
+
+        // step6. 混淆原.class文件(即:清空方法体)
         clearClassMethod(allNeedEncryptedClassFileList);
-        showProcess("step06", lastStep, "clear-class-method");
+        showProcess("step07", lastStep, "clear-class-method");
     
-        // step6. 清除META-INF/maven下pom.xml中关于class-winter-plugin的相关信息
+        // step7. 清除META-INF/maven下pom.xml中关于class-winter-plugin的相关信息
         clearWinterPluginInfo();
-        showProcess("step07", lastStep, "clear-winter-plugin-info");
+        showProcess("step08", lastStep, "clear-winter-plugin-info");
         
-        // step7. 添加class-winter的用于javaagent解密的代码
+        // step8. 添加class-winter的用于javaagent解密的代码
         addClassWinterAgent();
-        showProcess("step08", lastStep, "add-class-winter-agent");
+        showProcess("step09", lastStep, "add-class-winter-agent");
         
-        // step8. 汇总那些在本次加密前本身就已经是被class-winter混淆的lib的相关信息到当前项目中
+        // step9. 汇总那些在本次加密前本身就已经是被class-winter混淆的lib的相关信息到当前项目中
         collectAlreadyProtectedLibInfo();
-        showProcess("step09", lastStep, "collect-already-protected-lib-info");
+        showProcess("step10", lastStep, "collect-already-protected-lib-info");
         
-        // step9. 与step1项对应,将临时目录还原为原来的lib(此时得到的lib是加密后的)
+        // step10. 与step1项对应,将临时目录还原为原来的lib(此时得到的lib是加密后的)
         doLibJar();
-        showProcess("step10", lastStep, "do-lib-jar");
+        showProcess("step11", lastStep, "do-lib-jar");
         
-        // step10. 压缩targetRootDir目录为绝对文件路径名为generatedJarWar的jar(or war)包
+        // step11. 压缩targetRootDir目录为绝对文件路径名为generatedJarWar的jar(or war)包
         String generatedJarWar = generateJarWarPath(this.originIsJar);
         JarUtil.doJarWar(targetRootDir, generatedJarWar, new SimpleFileOrderSupport(filePathList));
-        showProcess("step11", lastStep, "generate-jar-war-path");
+        showProcess("step12", lastStep, "generate-jar-war-path");
         
-        // step11. 删除临时目录
+        // step12. 删除临时目录
         IOUtil.delete(targetRootDirFile);
         showProcess(lastStep, lastStep, "delete-tmp-dir");
         return generatedJarWar;
@@ -632,6 +642,26 @@ public class EncryptExecutor {
         IOUtil.writeContentToFile(Constant.SEAL, new File(targetRootDir, Constant.SEAL_FILE));
     }
     
+    /**
+     * 生成记录启动jar包时需要检查的输入参数项文件
+     */
+    private void generateJvmStartCheckItems() {
+        String content;
+        if (jvmStartCheckSet == null || jvmStartCheckSet.size() == 0) {
+            content = Constant.JVM_START_CHECK_NO_ITEM_CONTENT;
+        } else {
+            StringBuilder sb = new StringBuilder(64);
+            for (String checkItem : jvmStartCheckSet) {
+                sb.append(checkItem).append(Constant.WHITE_SPACE);
+            }
+            content = sb.toString();
+        }
+        Logger.debug(EncryptExecutor.class, "Generate jvmStartCheckItems -> " + content);
+//        content = Base64.getEncoder().encodeToString(content.getBytes(StandardCharsets.UTF_8));
+//        final byte[] encryptedBytes = EncryptUtil.encrypt(content.getBytes(StandardCharsets.UTF_8), obtainPassword());
+        IOUtil.toFile(content.getBytes(StandardCharsets.UTF_8), new File(targetRootDir, Constant.JVM_START_CHECK_FILE), true);
+    }
+    
     /**
      * 添加class-winter的用于javaagent解密的代码
      */
@@ -904,6 +934,7 @@ public class EncryptExecutor {
                 // 密码脱敏
                 ", password='" + (StrUtil.isBlank(password) ? null : "******") + '\'' +
                 ", supportFile='" + supportFile + '\'' +
+                ", jvmStartCheckSet='" + jvmStartCheckSet + '\'' +
                 ", includePrefixSet=" + includePrefixSet +
                 ", excludePrefixSet=" + excludePrefixSet +
                 ", includeXmlPrefixSet=" + includeXmlPrefixSet +
@@ -945,6 +976,8 @@ public class EncryptExecutor {
         
         private String supportFile;
         
+        private String jvmStartCheck;
+        
         private Boolean debug = false;
         
         private String tips;
@@ -1004,6 +1037,11 @@ public class EncryptExecutor {
             return this;
         }
         
+        public Builder jvmStartCheck(String jvmStartCheck) {
+            this.jvmStartCheck = jvmStartCheck;
+            return this;
+        }
+        
         public Builder debug(Boolean debug) {
             this.debug = debug;
             return this;
@@ -1103,11 +1141,13 @@ public class EncryptExecutor {
             
             // xml相关参数解析
             Set<String> includeXmlPrefixSet = StrUtil.strToSet(includeXmlPrefix);
+            Set<String> jvmStartCheckSet = StrUtil.strToSet(jvmStartCheck);
             Set<String> excludeXmlPrefixSet = StrUtil.strToSet(excludeXmlPrefix);
             toCleanXmlChildElementName = StrUtil.isBlank(toCleanXmlChildElementName) ? Constant.DEFAULT_XML_NODE_NAMES : toCleanXmlChildElementName;
             Set<String> toCleanXmlChildElementNameSet = StrUtil.strToSet(toCleanXmlChildElementName);
             return new EncryptExecutor(this.originJarOrWar, originIsJar, this.finalName, targetRootDir, targetLibDir, targetClassesDir,
-                    password, includeXmlPrefixSet, excludeXmlPrefixSet, toCleanXmlChildElementNameSet, includePrefixSet, excludePrefixSet, includeLibSet, alreadyProtectedLibSet, this.supportFile);
+                    password, includeXmlPrefixSet, excludeXmlPrefixSet, toCleanXmlChildElementNameSet, includePrefixSet,
+                    excludePrefixSet, includeLibSet, alreadyProtectedLibSet, this.supportFile, jvmStartCheckSet);
         }
     
         /**

+ 1 - 1
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Cache.java

@@ -27,7 +27,7 @@ public final class Cache {
     public static Map<String, char[]> passwordCacheForEncrypt = new HashMap<>(8);
     
     /** 本项目加密时的印章 */
-    public static String sealCache = null;
+    public static volatile String sealCache = null;
     
     /**
      * 以key-value的形式记录lib的印章。(key-存放采集到的类所在lib的信息的文件夹, value-印章字符串)

+ 15 - 1
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Constant.java

@@ -18,7 +18,6 @@ public interface Constant {
      */
     StringBuffer TIPS = new StringBuffer("ERROR !!!!!!!!!!! Jar(or War) has been protected by class-winter. Please use javaagent re-start project. !!!!!!!!!!!");
     
-    
     /**
      * 印章, 若class中存在此印章内容,也能说明该class被class-winter加密过
      */
@@ -84,6 +83,21 @@ public interface Constant {
      */
     String SEAL_FILE_SIMPLE_NAME = "seal.winter";
     
+    /**
+     * 记录启动jar包时需要检查的输入参数项文件 文件名
+     */
+    String JVM_START_CHECK_FILE_SIMPLE_NAME = "jscf.winter";
+    
+    /**
+     * 记录启动jar包时需要检查的输入参数项文件
+     */
+    String JVM_START_CHECK_FILE = DEFAULT_ENCRYPTED_BASE_SAVE_DIR + JVM_START_CHECK_FILE_SIMPLE_NAME;
+    
+    /**
+     * 当JVM_START_CHECK_FILE无检查项时,填写的默认值
+     */
+    String JVM_START_CHECK_NO_ITEM_CONTENT = "NON_CHECK_ITEM_AT_CLASS-WINTER";
+    
     /**
      * pom.xml文件所在的祖辈目录
      */

+ 1 - 1
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/AllTest.java

@@ -73,7 +73,7 @@ public class AllTest {
         String tips = "方法已经被class-winter加密保护了,请不要直接使用java -jar xxx.jar启动项目,请使用java -javaagent:xxx.jar -jar xxx.jar启动项目.";
         String alreadyProtectedLibs = "encrypted-lib-have-pwd-1.0.0.jar:qwer123~";
         String debug = "true";
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " excludePrefix=" + excludePrefix

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

@@ -67,7 +67,7 @@ public class AlreadyProtectedLibs_Test {
         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 " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " alreadyProtectedLibs=" + alreadyProtectedLibs
@@ -110,7 +110,7 @@ public class AlreadyProtectedLibs_Test {
         String includePrefix = "non-exist";
         String alreadyProtectedLibs = "encrypted-lib-have-pwd-1.0.0.jar:qwer123~";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " alreadyProtectedLibs=" + alreadyProtectedLibs

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

@@ -36,7 +36,7 @@ public class Debug_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 ;
@@ -64,7 +64,7 @@ public class Debug_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true

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

@@ -38,7 +38,7 @@ public class ExcludePrefix_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com.aspire.ssm.util.AesEncryptDecryptUtil,com.aspire.ssm.util.DbSecurityBeanUtil";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true
@@ -72,7 +72,7 @@ public class ExcludePrefix_Test {
         String includePrefix = "com.aspire.ssm.util.AesEncryptDecryptUtil,com.aspire.ssm.util.DbSecurityBeanUtil";
         String excludePrefix = "com.aspire.ssm.util.DbSecurityBeanUtil";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " excludePrefix=" + excludePrefix

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

@@ -23,7 +23,7 @@ public class FinalName_Test {
         String includePrefix = "com";
         String finalName = "YiYaKaKa";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " finalName=" + finalName

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

@@ -42,7 +42,7 @@ public class IncludeLibs_Test {
         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 " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " includeLibs=" + includeLibs

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

@@ -39,7 +39,7 @@ public class IncludePrefix_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com.aspire.ssm.util";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true

+ 52 - 0
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/JvmStartCheck_Test.java

@@ -0,0 +1,52 @@
+package winter.com.ideaaedi.classwinter;
+
+import winter.com.ideaaedi.classwinter.author.JustryDeng;
+import winter.com.ideaaedi.classwinter.util.BashUtil;
+import winter.com.ideaaedi.classwinter.util.PathUtil;
+
+/**
+ * 测试jvmStartCheck
+ * <p>
+ *     jvmStartCheck: 在启动混淆包时,检查是否输入有(在加密时)指定的jvm参数
+ * </p>
+ * @author {@link JustryDeng}
+ * @since 2021/6/12 14:34:45
+ */
+public class JvmStartCheck_Test {
+    
+    public static void main(String[] args) {
+        jvmCheckJarTest();
+    }
+    
+    /**
+     * jar测试
+     */
+    public static void jvmCheckJarTest() {
+        // 杀下进程(以保证端口没有被占用)
+        BashUtil.killProcessByPorts("8080");
+        
+        String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
+        String originJarOrWar = projectRootDir + "boot-jar.jar";
+        String includePrefix = "com";
+    
+        String jvmArg = "-XX:+DisableAttachMechanism,-Xms1024M";
+        
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
+                + " originJarOrWar=" + originJarOrWar
+                + " includePrefix=" + includePrefix
+                + " jvmStartCheck=" + jvmArg
+                + " debug=true"
+                ;
+        // 加密
+        BashUtil.runBashAndPrint(startBat);
+    
+    
+        String encryptedJar = originJarOrWar.replace(".jar", "-encrypted.jar");
+    
+        // 解密
+        String javaagentArgs = "";
+        // String javaagentArgs = "=debug=true";
+        // String javaagentArgs = "=debug=true,password=xxx";
+        BashUtil.runBashAndPrint(String.format("java -javaagent:%s%s=debug=true -jar %s", encryptedJar, javaagentArgs, encryptedJar));
+    }
+}

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

@@ -32,7 +32,7 @@ public class OriginJarOrWar_Test {
         String originJarOrWar = projectRootDir + "non-exist.jar";
         String includePrefix = "com.aspire.ssm.util";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true
@@ -58,7 +58,7 @@ public class OriginJarOrWar_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com.aspire.ssm.util";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true

+ 3 - 3
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Password_Test.java

@@ -34,7 +34,7 @@ public class Password_Test {
         String includePrefix = "com";
         String password = "pwd123";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " password=" + password
@@ -65,7 +65,7 @@ public class Password_Test {
         String includePrefix = "com";
         String password = "pwd123";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " password=" + password
@@ -97,7 +97,7 @@ public class Password_Test {
         String includePrefix = "com";
         String password = "pwd123";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " password=" + password

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

@@ -42,7 +42,7 @@ public class SupportFile_Test {
         String originJarOrWar = projectRootDir + "normal-jar.jar";
         String includePrefix = "com";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 ;
@@ -62,7 +62,7 @@ public class SupportFile_Test {
         String includePrefix = "com";
         String supportFile = projectRootDir + "help";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " supportFile=" + supportFile

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

@@ -32,7 +32,7 @@ public class Tips_Test {
         String originJarOrWar = projectRootDir + "boot-jar.jar";
         String includePrefix = "com";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 ;
@@ -55,8 +55,8 @@ public class Tips_Test {
         String tips = "[潘嘎之交] 潘: 你别怪潘叔说话比较直白, 网络上的东西都是虚拟的, 你把握不住, 孩子! 因为这里的水很深...";
     
         // 如果tips值由一些特殊字符(如空格等)的话,可以用windows双引号(linux单引号)引起来。
-        // java -jar class-winter-core-2.4.0.jar originJarOrWar=/boot-jar.jar includePrefix=com tips="[潘嘎之交] 潘: 你别怪潘叔说话比较直白, 网络上的东西都是虚拟的, 你把握不住, 孩子! 因为这里的水很深..."
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        // java -jar class-winter-core-2.5.0.jar originJarOrWar=/boot-jar.jar includePrefix=com tips="[潘嘎之交] 潘: 你别怪潘叔说话比较直白, 网络上的东西都是虚拟的, 你把握不住, 孩子! 因为这里的水很深..."
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " tips=" + (BashUtil.IS_WINDOWS ? "\"".concat(tips).concat("\"") : "'".concat(tips).concat("'"));

+ 5 - 5
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/War_Test.java

@@ -34,7 +34,7 @@ public class War_Test {
         String originJarOrWar = projectRootDir + "war-project.war";
         String includePrefix = "com";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 ;
@@ -62,7 +62,7 @@ public class War_Test {
         String includePrefix = "com";
         String password = "123456";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " password=" + password
@@ -93,7 +93,7 @@ public class War_Test {
         String alreadyProtectedLibs = "encrypted-lib-no-pwd.jar";
         String password = "oop857857";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " alreadyProtectedLibs=" + alreadyProtectedLibs
@@ -124,7 +124,7 @@ public class War_Test {
         String alreadyProtectedLibs = "encrypted-lib-have-pwd.jar:qwer123~";
         String password = "yiyakaka";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " alreadyProtectedLibs=" + alreadyProtectedLibs
@@ -160,7 +160,7 @@ public class War_Test {
         String alreadyProtectedLibs = "encrypted-lib-have-pwd.jar:qwer123~";
         String debug = "true";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " excludePrefix=" + excludePrefix

+ 1 - 1
class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Xml_Test.java

@@ -31,7 +31,7 @@ public class Xml_Test {
         String toCleanXmlChildElementName = "select";
         
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.4.0.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.5.0.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " includeXmlPrefix=" + includeXmlPrefix

BIN=BIN
class-winter-core/src/test/resources/class-winter-core-2.4.0.jar → class-winter-core/src/test/resources/class-winter-core-2.5.0.jar


+ 1 - 1
class-winter-maven-plugin/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.idea-aedi</groupId>
         <artifactId>class-winter</artifactId>
-        <version>2.4.0</version>
+        <version>2.5.0</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 6 - 0
class-winter-maven-plugin/src/main/java/winter/com/ideaaedi/classwinter/plugin/ClassWinterPlugin.java

@@ -59,6 +59,9 @@ public class ClassWinterPlugin extends AbstractMojo {
     @Parameter
     private String supportFile;
     
+    @Parameter
+    private String jvmStartCheck;;
+    
     @Parameter
     private String tips;
     
@@ -81,6 +84,8 @@ public class ClassWinterPlugin extends AbstractMojo {
         Logger.debug("You config arg password -> " + password);
         Logger.debug("You config arg includeLibs -> " + includeLibs);
         Logger.debug("You config arg alreadyProtectedLibs -> " + alreadyProtectedLibs);
+        Logger.debug("You config arg supportFile -> " + supportFile);
+        Logger.debug("You config arg jvmStartCheck -> " + jvmStartCheck);
         Logger.debug("You config arg tips -> " + tips);
         Logger.debug("You config arg debug -> " + debug);
         
@@ -100,6 +105,7 @@ public class ClassWinterPlugin extends AbstractMojo {
                 .includeLibs(includeLibs)
                 .alreadyProtectedLibs(alreadyProtectedLibs)
                 .supportFile(supportFile)
+                .jvmStartCheck(jvmStartCheck)
                 .debug(debug)
                 .tips(tips)
                 .build();

+ 1 - 1
pom.xml

@@ -9,7 +9,7 @@
     </modules>
     <groupId>com.idea-aedi</groupId>
     <artifactId>class-winter</artifactId>
-    <version>2.4.0</version>
+    <version>2.5.0</version>
 
     <!-- 配置项目的基础信息 -->
     <name>class-winter</name>