Переглянути джерело

Merge branch 'master' into release-2.8.6

JustryDeng 2 роки тому
батько
коміт
260f9ee1e5
28 змінених файлів з 222 додано та 95 видалено
  1. 42 28
      README.md
  2. 1 1
      class-winter-core/pom.xml
  3. 1 1
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Forward.java
  4. 2 2
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/Reverses.java
  5. 23 13
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java
  6. 7 0
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/Constant.java
  7. 18 1
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/EncryptClassArgs.java
  8. 33 10
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/JavassistUtil.java
  9. 55 2
      class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/StrUtil.java
  10. 3 3
      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. 4 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/EncryptArgParam_Test.java
  14. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/ExcludePrefix_Test.java
  15. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/FinalName_Test.java
  16. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludeLibs_Test.java
  17. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/IncludePrefix_Test.java
  18. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/JvmArgCheck_Test.java
  19. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/OriginJarOrWar_Test.java
  20. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Password_Test.java
  21. 2 2
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/SupportFile_Test.java
  22. 3 3
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Tips_Test.java
  23. 5 5
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/War_Test.java
  24. 1 1
      class-winter-core/src/test/java/winter/com/ideaaedi/classwinter/Xml_Test.java
  25. BIN
      class-winter-core/src/test/resources/class-winter-core-2.8.6.jar
  26. BIN
      class-winter-core/src/test/resources/class-winter-core-enhance-2.8.6.jar
  27. 1 1
      class-winter-maven-plugin/pom.xml
  28. 1 1
      pom.xml

+ 42 - 28
README.md

@@ -45,14 +45,15 @@
 - #### <font face="幼圆" ><font face="幼圆"  color = "#86CA5E">**方式一**</font>:通过maven插件自动加密</font>
   ```xml
   <!--
-      class-winter插件
+      class-winter插件``
       注:自Maven3.0.3起, 绑定到同一phase的Maven插件将按照pom.xml中声明的顺序执行
       注:此插件最好放置在同一phase的最后执行。
+      注:此插件不具备打包功能,需要在此插件前有打包插件进行项目打包,否则加密不会生效。
   -->
   <plugin>
       <groupId>com.idea-aedi</groupId>
       <artifactId>class-winter-maven-plugin</artifactId>
-      <version>2.8.5</version>
+      <version>2.8.6</version>
       <!-- 相关配置 -->
       <configuration>
           <!-- <finalName></finalName>-->
@@ -83,15 +84,15 @@
   ```
   注:不必担心信息泄漏问题,使用此方式生成混淆的jar包时,会擦除pom.xml中关于class-winter-plugin的信息。
   
-- #### <font face="幼圆" ><font face="幼圆"  color = "#86CA5E">**方式二**</font>:通过 [**class-winter-core.jar**](https://gitee.com/JustryDeng/class-winter/raw/master/class-winter-core/src/test/resources/class-winter-core-2.8.5.jar) 主动加密</font>
+- #### <font face="幼圆" ><font face="幼圆"  color = "#86CA5E">**方式二**</font>:通过 [**class-winter-core.jar**](https://gitee.com/JustryDeng/class-winter/raw/master/class-winter-core/src/test/resources/class-winter-core-2.8.6.jar) 主动加密</font>
 
   ```bash
-  java -jar class-winter-core-2.8.5.jar originJarOrWar=${要加密的项目.jar或.war包} includePrefix=${加密范围} [k3=v3 k4=v4 ...]
+  java -jar class-winter-core-2.8.6.jar originJarOrWar=${要加密的项目.jar或.war包} includePrefix=${加密范围} [k3=v3 k4=v4 ...]
   # 对于复杂的参数值,可以使用引号引起来
   # linux
-  java -jar class-winter-core-2.8.5.jar k1='v1' k2='v2'
+  java -jar class-winter-core-2.8.6.jar k1='v1' k2='v2'
   # windows
-  java -jar class-winter-core-2.8.5.jar k1="v1" k2="v2"
+  java -jar class-winter-core-2.8.6.jar k1="v1" k2="v2"
   ```
 
 ## <font  face="幼圆" color = "#3399EA" >加密参数</font>
@@ -120,12 +121,15 @@
     <tr align="center">
     <td>includePrefix</td>
     <td>是</td>
-    <td>通过前缀匹配的形式定位要加密的class
+    <td>通过前缀匹配的形式定位要加密的class,支持正则匹配
     <br/>
 注:多个通过逗号分割。</td>
     <td>includePrefix=com
     <br/>
-includePrefix=com,org</td>
+includePrefix=com,org
+ <br/>
+includePrefix=com.*.dao,org
+</td>
   </tr>
  <tr align="center">
     <td>cca(依托于includePrefix)</td>
@@ -145,39 +149,48 @@ includePrefix=com,org</td>
     <td>作为includePrefix的附加设置,设置是否清空字段上的注解(写法同url后面设置参数)</td>
     <td>includePrefix=com?cca=true&cma=true&cfa=true</td>
   </tr>
+<tr align="center">
+    <td>caPrefix(依托于cca、cma、cfa开关)</td>
+    <td>否</td>
+    <td>作为includePrefix的附加设置,依托与cca、cma、cfa开关,清空类、方法、字段上的指定注解(写法同url后面设置参数)
+      <br/>
+注:多个通过|分割,注解请写完全路径例如:com.xx.anno.MyAnnotation  
+    </td>
+    <td>includePrefix=com?cca=true&cma=true&cfa=true&caPrefix=com.xx.anno.MyAnnotation|com.bb.anno.MyAnnotation</td>
+  </tr>
     <tr align="center">
     <td>excludePrefix</td>
     <td>否</td>
-    <td>通过前缀匹配的形式排除class,不对其加密
+    <td>通过前缀匹配的形式排除class,不对其加密,支持正则匹配
     <br/>
 注:多个通过逗号分割。
 <br/>
 注:excludePrefix优先级高于includePrefix。</td>
-    <td>excludePrefix=com.example.service,com.example.util.StrUtil.class</td>
+    <td>excludePrefix=com.example.service,com.example.util.*.class</td>
   </tr>
       </tr>
     <tr align="center">
     <td>includeXmlPrefix</td>
     <td>否</td>
-    <td>通过打出来的包中条目的entryName前缀匹配的形式定位要加密的xml
+    <td>通过打出来的包中条目的entryName前缀匹配的形式定位要加密的xml,支持正则匹配
     <br/>
 注:多个通过逗号分割。    
     <br/>
 注:如果您打出来的加密包是准备作为一个lib包提供给第三方使用的,那么请不要使用此参数,因为解密时是不会解密项目所依赖的lib包中的xml的。</td>
     <td>includeXmlPrefix=BOOT-INF/classes/
     <br/>
-includeXmlPrefix=BOOT-INF/classes/com/demo/mapper/,BOOT-INF/classes/com/demo/dao/</td>
+includeXmlPrefix=BOOT-INF/classes/com/demo/mapper/,BOOT-INF/classes/com/*/dao/</td>
   </tr>
   </tr>
     <tr align="center">
     <td>excludeXmlPrefix</td>
     <td>否</td>
-    <td>通过打出来的包中条目的entryName前缀匹配的形式排除xml,不对其加密
+    <td>通过打出来的包中条目的entryName前缀匹配的形式排除xml,不对其加密,支持正则匹配
     <br/>
 注:多个通过逗号分割。</td>
     <td>excludeXmlPrefix=BOOT-INF/classes/com/demo/mapper/
     <br/>
-excludeXmlPrefix=BOOT-INF/classes/com/demo/mapper/,BOOT-INF/classes/com/demo/dao/UserDao.xml</td>
+excludeXmlPrefix=BOOT-INF/classes/com/demo/mapper/,BOOT-INF/classes/com/demo/*/UserDao.xml</td>
   </tr>
   </tr>
     <tr align="center">
@@ -210,12 +223,12 @@ excludeXmlPrefix=BOOT-INF/classes/com/demo/mapper/,BOOT-INF/classes/com/demo/dao
     <tr align="center">
     <td>includeLibs</td>
     <td>否</td>
-    <td>指定将lib包也纳入加密范围内
+    <td>指定将lib包也纳入加密范围内,支持正则匹配
     <br/>
 注:多个通过逗号分割。
 <br/>
 注:lib中的class是否会被加密,还得由includePrefix和excludePrefix决定。</td>
-    <td>includeLibs=a.jar,b.jar</td>
+    <td>includeLibs=a.jar,b.jar,c-.*.jar</td>
   </tr>
     <tr align="center">
     <td>alreadyProtectedRootDir</td>
@@ -295,6 +308,7 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
 
 
 
+
 ## <font  face="幼圆" color = "#3399EA" >解密(启动)</font>
 
 通过-javaagent指定代理进行解密启动。
@@ -302,8 +316,8 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
   ```bash
   # 假设your-project-encrypted.jar是由class-winter加密后的包,那么你可以这么启动
   java -javaagent:/your-project-encrypted.jar -jar /your-project-encrypted.jar
-  # 也可以用class-winter-core-2.8.5.jar
-  # java -javaagent:/class-winter-core-2.8.5.jar -jar /your-project-encrypted.jar
+  # 也可以用class-winter-core-2.8.6.jar
+  # java -javaagent:/class-winter-core-2.8.6.jar -jar /your-project-encrypted.jar
   # 或者指定参数
   # java -javaagent:/your-project-encrypted.jar=debug=true,password=pwd12345 -jar /your-project-encrypted.jar
   # 参数可以引起来(linux)
@@ -319,9 +333,9 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
     编辑tomcat/bin/catalina.sh文件,在最上面加上
 
     ```bash
-    # 如果你有参数, 那么 -javaagent:/class-winter-core-2.8.5.jar=k1=v1,k2=v2
+    # 如果你有参数, 那么 -javaagent:/class-winter-core-2.8.6.jar=k1=v1,k2=v2
     # tomcat启动往往需要通过decryptProjectPathPrefix指定要解密的路径
-    CATALINA_OPTS="$CATALINA_OPTS -javaagent:/class-winter-core-2.8.5.jar=debug=true,decryptProjectPathPrefix=/usr/local/xxx/";
+    CATALINA_OPTS="$CATALINA_OPTS -javaagent:/class-winter-core-2.8.6.jar=debug=true,decryptProjectPathPrefix=/usr/local/xxx/";
     export CATALINA_OPTS;
     ```
   
@@ -330,9 +344,9 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
     在tomcat/bin目录下创建setenv.sh文件,并写上
   
     ```bash
-    # 如果你有参数, 那么 -javaagent:/class-winter-core-2.8.5.jar=k1=v1,k2=v2
+    # 如果你有参数, 那么 -javaagent:/class-winter-core-2.8.6.jar=k1=v1,k2=v2
     # tomcat启动往往需要通过decryptProjectPathPrefix指定要解密的路径
-    JAVA_OPTS="$JAVA_OPTS -javaagent:/class-winter-core-2.8.5.jar=debug=true,decryptProjectPathPrefix=/usr/local/xxx/";
+    JAVA_OPTS="$JAVA_OPTS -javaagent:/class-winter-core-2.8.6.jar=debug=true,decryptProjectPathPrefix=/usr/local/xxx/";
     export JAVA_OPTS;
     ```
 
@@ -341,9 +355,9 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
     编辑tomcat/bin/catalina.bat文件,在@echo off后加上catalina参数
   
     ```bash
-    rem 如果你有参数, 那么 -javaagent:D:/class-winter-core-2.8.5.jar=k1=v1,k2=v2
+    rem 如果你有参数, 那么 -javaagent:D:/class-winter-core-2.8.6.jar=k1=v1,k2=v2
     rem tomcat启动往往需要通过decryptProjectPathPrefix指定要解密的路径
-    set CATALINA_OPTS="-javaagent:D:/class-winter-core-2.8.5.jar=decryptProjectPathPrefix=/D:/tmp/"
+    set CATALINA_OPTS="-javaagent:D:/class-winter-core-2.8.6.jar=decryptProjectPathPrefix=/D:/tmp/"
     ```
   
   - windows方式二
@@ -351,9 +365,9 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
     在tomcat/bin目录下创建setenv.bat文件,并写上
   
     ```bash
-    rem 如果你有参数, 那么 -javaagent:D:/class-winter-core-2.8.5.jar=k1=v1,k2=v2
+    rem 如果你有参数, 那么 -javaagent:D:/class-winter-core-2.8.6.jar=k1=v1,k2=v2
     rem tomcat启动往往需要通过decryptProjectPathPrefix指定要解密的路径
-    set JAVA_OPTS="-javaagent:D:/class-winter-core-2.8.5.jar=decryptProjectPathPrefix=/D:/tmp/"
+    set JAVA_OPTS="-javaagent:D:/class-winter-core-2.8.6.jar=decryptProjectPathPrefix=/D:/tmp/"
     ```
   
 - #### <font  face="幼圆" color = "#86CA5E" >IDE解密(启动)</font>
@@ -425,7 +439,7 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
 
 - 背景说明:我们利用class-winter混淆项目时,项目是被混淆了,但是class-winter本身还是明文的,这就留下了一些安全隐患(即:那些不指定密码的混淆,可能会被反向破解)
 - 增强支持:我们可以对class-winter本身进行加密,你可以切换至`enhance-*`分支,在首页下载被混淆的class-winter进行测试,或者clone代码,install后进行测试
-- <font face="幼圆"  color = "#F53B45">**声明**</font>:因为在`enhance-*`分支里对class-winter本身进行加密时用到了名义上的收费工具allatori(实际上有破解版之类的),所以`enhance-*`分支的代码,本人并未发布至maven官方仓库
+- <font face="幼圆"  color = "#F53B45">**声明**</font>:因为在`enhance-*`分支里对class-winter本身进行加密时用到了收费工具allatori(实际上有供学习使用的破解版之类的),所以`enhance-*`分支的代码,本人并未发布至maven官方仓库
 
 
 ## <font  face="幼圆" color = "#3399EA" >将已加密的包提供给客户使用</font>
@@ -464,7 +478,7 @@ linux示例:tips='请不要直接使用混淆后的jar/war'</td>
       <parent>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-parent</artifactId>
-          <version>2.8.5</version>
+          <version>2.8.6</version>
           <relativePath/> <!-- lookup parent from repository -->
       </parent>
       <groupId>com.example</groupId>

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

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

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

@@ -17,7 +17,7 @@ public class Forward {
     
     /**
      * 入口
-     *
+     * <p>
      * 假设是这么java -jar -class-winter-core-1.0.0.jar k1=v1 k2=v2 k3=v3  启动项目的,
      * 那么args的内容形如["k1=v1", "k2=v2", "k3=v3"]
      */

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

@@ -74,7 +74,7 @@ public class Reverses {
             String[] projectPathItem = skipProjectPathPrefix.split("___");
             for (String projectPathPrefix : projectPathItem) {
                 if (!StrUtil.isBlank(projectPathPrefix)) {
-                    skipProjectPathPrefixSet.add(projectPathPrefix.trim());
+                    skipProjectPathPrefixSet.add(projectPathPrefix.trim().replace("\\","/"));
                 }
             }
         }
@@ -86,7 +86,7 @@ public class Reverses {
             String[] projectPathItem = decryptProjectPathPrefix.split("___");
             for (String projectPathPrefix : projectPathItem) {
                 if (!StrUtil.isBlank(projectPathPrefix)) {
-                    decryptProjectPathPrefixSet.add(projectPathPrefix.trim());
+                    decryptProjectPathPrefixSet.add(projectPathPrefix.trim().replace("\\","/"));
                 }
             }
         }

+ 23 - 13
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/executor/EncryptExecutor.java

@@ -155,6 +155,11 @@ public class EncryptExecutor {
      * </pre>
      */
     private final Set<String> includeLibSet;
+
+    /**
+     * 如果这次需要加密的lib本身就已经是被加密了的,那么这次不再对其进行加密
+     */
+    private final Set<String> protectedLibSet;
     
     /**
      * 不需要加密的类的全类名前缀(也可以精确匹配)
@@ -223,7 +228,7 @@ public class EncryptExecutor {
     private EncryptExecutor(String originJarOrWar, boolean originIsJar, String finalName, String targetRootDir,
                             String targetLibDir, String targetClassesDir, String password,
                             Set<String> includeXmlPrefixSet, Set<String> excludeXmlPrefixSet, Set<String> toCleanXmlChildElementNameSet,
-                            LinkedHashSet<String> includePrefixSet, Set<String> excludePrefixSet, Set<String> includeLibSet,
+                            LinkedHashSet<String> includePrefixSet, Set<String> excludePrefixSet, Set<String> includeLibSet, Set<String> protectedLibSet,
                             String alreadyProtectedRootDir, Set<Pair<String, String>> alreadyProtectedLibSet,
                             String supportFile, Set<String> jvmArgCheckSet) {
         this.originJarOrWar = originJarOrWar;
@@ -239,6 +244,7 @@ public class EncryptExecutor {
         this.includePrefixSet = includePrefixSet;
         this.excludePrefixSet = excludePrefixSet;
         this.includeLibSet = includeLibSet;
+        this.protectedLibSet = protectedLibSet;
         this.alreadyProtectedRootDir = alreadyProtectedRootDir;
         this.alreadyProtectedLibSet = alreadyProtectedLibSet;
         this.supportFile = supportFile;
@@ -344,12 +350,12 @@ public class EncryptExecutor {
                 })
                 .filter(zipEntryName -> {
                     if (excludeXmlPrefixSet != null) {
-                        boolean shouldExclude = excludeXmlPrefixSet.stream().anyMatch(zipEntryName::startsWith);
+                        boolean shouldExclude = excludeXmlPrefixSet.stream().anyMatch(s -> StrUtil.startsWithOrRegMatched(s, zipEntryName));
                         if (shouldExclude) {
                             return false;
                         }
                     }
-                    return includeXmlPrefixSet.stream().anyMatch(zipEntryName::startsWith);
+                    return includeXmlPrefixSet.stream().anyMatch(s -> StrUtil.startsWithOrRegMatched(s, zipEntryName));
                 })
                 .collect(Collectors.toSet());
         
@@ -628,8 +634,8 @@ public class EncryptExecutor {
         // 罗列出targetRootDir下的所有.jar文件
         List<File> allJarFiles = IOUtil.listFileOnly(new File(targetRootDir), Constant.JAR_SUFFIX);
         // 筛选出需要加密的lib包
-        List<File> neededEncryptedLibs =  allJarFiles.stream().filter(jarFile -> includeLibSet.contains(jarFile.getName())).collect(Collectors.toList());
-    
+        List<File> neededEncryptedLibs = allJarFiles.stream().filter(jarFile -> !protectedLibSet.contains(jarFile.getName()) &&
+                includeLibSet.stream().anyMatch(s -> StrUtil.startsWithOrRegMatched(s, jarFile.getName()))).collect(Collectors.toList());
         // 依次解密
         neededEncryptedLibs.forEach(jar -> {
             // 假设: jarAbsolutePath为  /xyz/abc.jar
@@ -943,7 +949,7 @@ public class EncryptExecutor {
                     String classLongName = JavassistUtil.resolveClassName(file.getAbsolutePath(), true);
                     if (excludePrefixSet != null) {
                         for (String excludePrefix : excludePrefixSet) {
-                            if (classLongName.startsWith(excludePrefix)) {
+                            if (StrUtil.startsWithOrRegMatched(excludePrefix, classLongName)) {
                                 // 排除
                                 return null;
                             }
@@ -955,13 +961,14 @@ public class EncryptExecutor {
                             Pair<String, Map<String, String>> pair = extraPrefixAndParam(includePrefix);
                             String pureIncludePrefix = pair.getLeft();
                             Map<String, String> params = pair.getRight();
-                            
-                            if (classLongName.startsWith(pureIncludePrefix)) {
+
+                            if (StrUtil.startsWithOrRegMatched(pureIncludePrefix, classLongName)) {
                                 // 包含
                                 return EncryptClassArgs.create(file,
                                         StrUtil.isTrueDefault(params.get(Constant.CLEAN_CLASS_ANNOTATION_PARAM_NAME), false),
                                         StrUtil.isTrueDefault(params.get(Constant.CLEAN_METHOD_ANNOTATION_PARAM_NAME), false),
-                                        StrUtil.isTrueDefault(params.get(Constant.CLEAN_FIELD_ANNOTATION_PARAM_NAME), false)
+                                        StrUtil.isTrueDefault(params.get(Constant.CLEAN_FIELD_ANNOTATION_PARAM_NAME), false),
+                                        params.get(Constant.TO_CLEAN_FIELD_ANNOTATION_PREFIX)
                                 );
                             }
                         }
@@ -1091,6 +1098,7 @@ public class EncryptExecutor {
                 ", excludeXmlPrefixSet=" + excludeXmlPrefixSet +
                 ", toCleanChildElementNameSet=" + toCleanXmlChildElementNameSet +
                 ", includeLibSet=" + includeLibSet +
+                ", protectedLibSet=" + protectedLibSet +
                 ", alreadyProtectedLibSet=" + alreadyProtectedLibSet +
                 '}';
     }
@@ -1281,12 +1289,14 @@ public class EncryptExecutor {
             Set<String> excludePrefixSet = StrUtil.strToSet(excludePrefix);
             Set<String> includeLibSet = StrUtil.strToSet(includeLibs);
             Set<Pair<String, String>> alreadyProtectedLibSet = parseAlreadyProtectedLibs();
-            
+
+            Set<String> matchAlreadyProtectedLibSet = new HashSet<>();
+
             // 如果这次需要加密的lib本身就已经是被加密了的,那么这次不再对其进行加密
             alreadyProtectedLibSet.stream().map(Pair::getLeft).forEach(lib -> {
-                if (includeLibSet.contains(lib)) {
+                if (includeLibSet.stream().anyMatch(s -> StrUtil.startsWithOrRegMatched(s, lib))) {
                     Logger.warn(EncryptExecutor.class, "Ignore includeLibs item [" + lib + "], because this item already be protected by class-winter.");
-                    includeLibSet.remove(lib);
+                    matchAlreadyProtectedLibSet.add(lib);
                 }
             });
             
@@ -1307,7 +1317,7 @@ public class EncryptExecutor {
             
             return new EncryptExecutor(this.originJarOrWar, originIsJar, this.finalName, targetRootDir, targetLibDir, targetClassesDir,
                     password, includeXmlPrefixSet, excludeXmlPrefixSet, toCleanXmlChildElementNameSet, includePrefixSortSet,
-                    excludePrefixSet, includeLibSet, alreadyProtectedRootDir, alreadyProtectedLibSet, this.supportFile, jvmArgCheckSet);
+                    excludePrefixSet, includeLibSet,matchAlreadyProtectedLibSet, alreadyProtectedRootDir, alreadyProtectedLibSet, this.supportFile, jvmArgCheckSet);
         }
     
         /**

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

@@ -255,4 +255,11 @@ public interface Constant {
      * {@link EncryptClassArgs#isCleanAnnotationOverField()}
      */
     String CLEAN_FIELD_ANNOTATION_PARAM_NAME = "cfa";
+
+    /**
+     * 参数名:加密的类需要清除的注解全类名前缀(也可以精确匹配),不指定则为默认规则全部注解清除. 分隔符为|符号,例如:com.kk.verify|com.xx.sun
+     * <p>
+     * {@link EncryptClassArgs#getToCleanAnnotationPrefix()}
+     */
+    String TO_CLEAN_FIELD_ANNOTATION_PREFIX = "caPrefix";
 }

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

@@ -31,6 +31,11 @@ public class EncryptClassArgs {
      * 是否清除字段的注解
      */
     private boolean cleanAnnotationOverField = false;
+
+    /**
+     * 加密的类需要清除的注解全类名前缀(也可以精确匹配),不指定则为默认规则全部注解清除. 分隔符为|符号,例如:com.xx.verify|com.xx.sun
+     */
+    private String toCleanAnnotationPrefix = "";
     
     /**
      * 是否保留原方法的参数名
@@ -41,13 +46,16 @@ public class EncryptClassArgs {
      * fast create
      */
     public static EncryptClassArgs create(File encryptClassFile, boolean cleanAnnotationOverClazz,
-                                          boolean cleanAnnotationOverMethod, boolean cleanAnnotationOverField) {
+                                          boolean cleanAnnotationOverMethod, boolean cleanAnnotationOverField,
+            String toCleanAnnotationPrefix) {
         Objects.requireNonNull(encryptClassFile, "encryptClassFile cannot be null.");
         EncryptClassArgs encryptClassArgs = new EncryptClassArgs();
         encryptClassArgs.setEncryptClassFile(encryptClassFile);
         encryptClassArgs.setCleanAnnotationOverClazz(cleanAnnotationOverClazz);
         encryptClassArgs.setCleanAnnotationOverMethod(cleanAnnotationOverMethod);
         encryptClassArgs.setCleanAnnotationOverField(cleanAnnotationOverField);
+        encryptClassArgs.setToCleanAnnotationPrefix(toCleanAnnotationPrefix);
+
         return encryptClassArgs;
     }
     
@@ -82,6 +90,14 @@ public class EncryptClassArgs {
     public void setCleanAnnotationOverField(boolean cleanAnnotationOverField) {
         this.cleanAnnotationOverField = cleanAnnotationOverField;
     }
+
+    public String getToCleanAnnotationPrefix() {
+        return toCleanAnnotationPrefix;
+    }
+
+    public void setToCleanAnnotationPrefix(String toCleanAnnotationPrefix) {
+        this.toCleanAnnotationPrefix = toCleanAnnotationPrefix;
+    }
     
     public boolean isKeepOriginArgsName() {
         return keepOriginArgsName;
@@ -98,6 +114,7 @@ public class EncryptClassArgs {
                 ", cleanAnnotationOverClazz=" + cleanAnnotationOverClazz +
                 ", cleanAnnotationOverMethod=" + cleanAnnotationOverMethod +
                 ", cleanAnnotationOverField=" + cleanAnnotationOverField +
+                ", toCleanAnnotationPrefix=" + toCleanAnnotationPrefix +
                 ", keepOriginArgsName=" + keepOriginArgsName +
                 '}';
     }

+ 33 - 10
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/JavassistUtil.java

@@ -13,6 +13,7 @@ import javassist.bytecode.Bytecode;
 import javassist.bytecode.CodeAttribute;
 import javassist.bytecode.CodeIterator;
 import javassist.bytecode.ExceptionTable;
+import javassist.bytecode.annotation.Annotation;
 import javassist.compiler.CompileError;
 import javassist.compiler.Javac;
 import winter.com.ideaaedi.classwinter.author.JustryDeng;
@@ -20,6 +21,7 @@ import winter.com.ideaaedi.classwinter.exception.ClassWinterException;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -59,9 +61,11 @@ public final class JavassistUtil {
             boolean cleanOverCLass = encryptClassArgs.isCleanAnnotationOverClazz();
             boolean cleanOverMethod = encryptClassArgs.isCleanAnnotationOverMethod();
             boolean cleanOverField = encryptClassArgs.isCleanAnnotationOverField();
+            String toCleanAnnotationPrefix = encryptClassArgs.getToCleanAnnotationPrefix();
+
             if (cleanOverCLass || cleanOverMethod || cleanOverField) {
                 try {
-                    clearAnnotation(ctClass, cleanOverCLass, cleanOverMethod, cleanOverField);
+                    clearAnnotation(ctClass, cleanOverCLass, cleanOverMethod, cleanOverField, toCleanAnnotationPrefix);
                 } catch (Exception ignore) {
                     Logger.warn(JavassistUtil.class, "clean className [" + className + "] annotation fail. ignore.");
                     // ignore
@@ -113,23 +117,23 @@ public final class JavassistUtil {
      * @param cleanOverMethod 是否清空方法上的注解
      * @param cleanOverField 是否清空字段上的注解
      */
-    private static void clearAnnotation(CtClass ctClass, boolean cleanOverCLass, boolean cleanOverMethod, boolean cleanOverField) {
+    private static void clearAnnotation(CtClass ctClass, boolean cleanOverCLass, boolean cleanOverMethod, boolean cleanOverField, String toCleanAnnotationPrefix) {
         // 清空类上的注解
         if (cleanOverCLass) {
-            removeAnnotationsAttribute(ctClass.getClassFile().getAttributes());
+            removeAnnotationsAttribute(ctClass.getClassFile().getAttributes(), toCleanAnnotationPrefix);
         }
         // 清空方法上的注解
         if (cleanOverMethod) {
             CtMethod[] methods = ctClass.getDeclaredMethods();
             for (CtMethod ctMethod : methods) {
-                removeAnnotationsAttribute(ctMethod.getMethodInfo().getAttributes());
+                removeAnnotationsAttribute(ctMethod.getMethodInfo().getAttributes(), toCleanAnnotationPrefix);
             }
         }
         // 清空字段上的注解
         if (cleanOverField) {
             CtField[] fields = ctClass.getDeclaredFields();
             for (CtField declaredField : fields) {
-                removeAnnotationsAttribute(declaredField.getFieldInfo().getAttributes());
+                removeAnnotationsAttribute(declaredField.getFieldInfo().getAttributes(), toCleanAnnotationPrefix);
             }
         }
     }
@@ -141,17 +145,36 @@ public final class JavassistUtil {
      * @return 操作是否成功
      */
     @SuppressWarnings("UnusedReturnValue")
-    private static boolean removeAnnotationsAttribute(List<AttributeInfo> attributeInfoList) {
+    private static boolean removeAnnotationsAttribute(List<AttributeInfo> attributeInfoList, String toCleanAnnotationPrefix) {
         if (attributeInfoList == null || attributeInfoList.size() == 0) {
             return true;
         }
-        return attributeInfoList.removeIf(x -> {
+        // 匹配注解全部删除
+        if (StrUtil.isBlank(toCleanAnnotationPrefix)) {
+            return attributeInfoList.removeIf(x -> {
+                try {
+                    return x instanceof AnnotationsAttribute;
+                } catch (Exception e) {
+                    return false;
+                }
+            });
+        }
+        // 删除指定注解
+        StrUtil.strToSet(toCleanAnnotationPrefix, "\\|").forEach(x -> attributeInfoList.forEach(y -> {
             try {
-                return x instanceof AnnotationsAttribute;
+                if (y instanceof AnnotationsAttribute) {
+                    AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) y;
+                    Annotation[] annotations = annotationsAttribute.getAnnotations();
+                    Annotation[] newAnnotations = Arrays.stream(annotations)
+                            .filter(annotation -> !annotation.getTypeName().startsWith(x))
+                            .toArray(Annotation[]::new);
+                    annotationsAttribute.setAnnotations(newAnnotations);
+                }
             } catch (Exception e) {
-                return false;
+                throw e;
             }
-        });
+        }));
+        return true;
     }
     
     /**

+ 55 - 2
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/StrUtil.java

@@ -8,6 +8,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 /**
  * 字符串工具类
@@ -114,19 +115,31 @@ public final class StrUtil {
         }
         return newStr.toString();
     }
+
+    /**
+     * 将由逗号分割的信息分割到set里面
+     *
+     * @param str 逗号分割的字符串
+     * @return 承载各个前缀信息的集合
+     */
+    public static Set<String> strToSet(String str) {
+        return strToSet(str, ",");
+    }
     
     /**
      * 将由逗号分割的信息分割到set里面
      *
      * @param str
      *            逗号分割的字符串
+     * @param split
+     *            分隔符
      * @return  承载各个前缀信息的集合
      */
-    public static Set<String> strToSet(String str) {
+    public static Set<String> strToSet(String str, String split) {
         Set<String> set = new HashSet<>();
         if (!StrUtil.isBlank(str)) {
             str = str.trim();
-            String[] arr = str.split(",");
+            String[] arr = str.split(split);
             for (String item : arr) {
                 if (StrUtil.isEmpty(item)) {
                     continue;
@@ -178,4 +191,44 @@ public final class StrUtil {
         Arrays.fill(byteBuffer.array(), (byte) 0);
         return bytes;
     }
+
+    /**
+     * 检查字符串是否以指定的前缀或正则表达式匹配。
+     *
+     * @param prefixOrRegex
+     *              前缀或正则表达式字符串
+     * @param text
+     *              待匹配字符串
+     * @return 如果前缀匹配或正则表达式匹配成功,返回 true;否则返回 false。
+     */
+    public static boolean startsWithOrRegMatched(String prefixOrRegex, String text) {
+        return prefixOrRegex.startsWith(text) || regMatched(prefixOrRegex, text);
+    }
+
+
+    /**
+     * 获取正则表达式匹配次数
+     *
+     * @param patternStr
+     *              正则表达式字符串
+     * @param text
+     *              待匹配字符串
+     * @return 匹配次数
+     */
+    public static boolean regMatched(String patternStr, String text) {
+        return regMatched(Pattern.compile(patternStr), text);
+    }
+
+    /**
+     * 获取正则表达式匹配次数
+     *
+     * @param pattern
+     *            正则表达式匹配器
+     * @param text
+     *          待匹配字符串
+     * @return 匹配次数
+     */
+    public static boolean regMatched(Pattern pattern, String text) {
+        return pattern.matcher(text).find();
+    }
 }

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

@@ -68,16 +68,16 @@ public class AllTest {
         // 加密
         String projectRootDir = PathUtil.getProjectRootDir(AllTest.class);
         String originJarOrWar = projectRootDir + "my-project-with-encrypted-lib-have-pwd.jar";
-        String includePrefix = "com.szlaozicl?cca=true&cfa=true,com.aspire.ssm,org.springframework.aop.target.dynamic,com.fasterxml.jackson";
+        String includePrefix = "com.szlaozicl?cca=true&cfa=true,com.aspire.ssm,org.springframework.aop.target.dynamic,com.*.jackson";
         String excludePrefix = "com.aspire.ssm.config,com.aspire.ssm.util.Person";
         String finalName = "jd";
         String password = "pwd12345";
-        String includeLibs = "spring-aop-5.2.7.RELEASE.jar,jackson-core-2.10.4.jar";
+        String includeLibs = "spring-aop-5.2.7.RELEASE.jar,jackson-.*.jar";
         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 jvmArgCheck = "-XX:+DisableAttachMechanism";
         String debug = "true";
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true

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

@@ -42,6 +42,9 @@ public class EncryptArgParam_Test {
         argMap.put(Constant.CLEAN_CLASS_ANNOTATION_PARAM_NAME, "true");  // 默认为false
         argMap.put(Constant.CLEAN_METHOD_ANNOTATION_PARAM_NAME, "false");  // 默认为false
         argMap.put(Constant.CLEAN_FIELD_ANNOTATION_PARAM_NAME, "true"); // 默认为false
+        // 这里仅作测试实际清除spring boot注解会有问题 ,spring ClassReader读的是本地classfile 所以清除的spring 注解读取不到了
+        argMap.put(Constant.TO_CLEAN_FIELD_ANNOTATION_PREFIX, "org.springframework.context.annotation.Configuration"); // 默认为''
+
         have(argMap);
     }
     
@@ -67,7 +70,7 @@ public class EncryptArgParam_Test {
             includePrefix= sb.toString();
         }
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=true"

+ 3 - 3
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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true
@@ -70,9 +70,9 @@ public class ExcludePrefix_Test {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
         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 excludePrefix = "com.aspire.*.DbSecurityBeanUtil";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.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.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " finalName=" + finalName

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

@@ -40,9 +40,9 @@ public class IncludeLibs_Test {
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
         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 includeLibs = "spring-aop-.*.RELEASE.jar,guava-28.2-jre.jar";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " includeLibs=" + includeLibs

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

@@ -37,9 +37,9 @@ public class IncludePrefix_Test {
         BashUtil.killProcessByPorts("8080");
         String projectRootDir = PathUtil.getProjectRootDir(AlreadyProtectedLibs_Test.class);
         String originJarOrWar = projectRootDir + "boot-jar.jar";
-        String includePrefix = "com.aspire.ssm.util";
+        String includePrefix = "com.aspire.*.util";
     
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " debug=" + true

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

@@ -33,7 +33,7 @@ public class JvmArgCheck_Test {
     
         String jvmArg = "-XX:+DisableAttachMechanism,-Xms1024M";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " jvmArgCheck=" + jvmArg
@@ -65,7 +65,7 @@ public class JvmArgCheck_Test {
     
         String jvmArg = "-XX:+DisableAttachMechanism,-Xms1024M";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " jvmArgCheck=" + jvmArg
@@ -97,7 +97,7 @@ public class JvmArgCheck_Test {
     
         String jvmArg = "-XX:+DisableAttachMechanism";
         
-        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.5.jar"
+        String startBat = "java -jar " + projectRootDir + "class-winter-core-2.8.6.jar"
                 + " originJarOrWar=" + originJarOrWar
                 + " includePrefix=" + includePrefix
                 + " jvmArgCheck=" + jvmArg

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

BIN
class-winter-core/src/test/resources/class-winter-core-2.8.6.jar


BIN
class-winter-core/src/test/resources/class-winter-core-enhance-2.8.6.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.8.5</version>
+        <version>2.8.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
pom.xml

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