├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main └── java └── io └── xjar ├── XAntEntryFilter.java ├── XArray.java ├── XBuilder.java ├── XExcludeAntEntryFilter.java └── XIncludeAntEntryFilter.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | 11 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 12 | !/.mvn/wrapper/maven-wrapper.jar 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XJar-Maven-Plugin [![](https://jitpack.io/v/core-lib/xjar-maven-plugin.svg)](https://jitpack.io/#core-lib/xjar-maven-plugin) 2 | #### XJar-Maven-Plugin 是对 [XJar](https://github.com/core-lib/xjar) 的一个Maven Plugin封装,实现可通过Maven命令或绑定在Maven构建的生命周期之中执行,用以更加便捷的方式集成 [XJar](https://github.com/core-lib/xjar) 。 3 | 4 | GitHub: https://github.com/core-lib/xjar-maven-plugin 5 | 6 | ## 什么是XJar 7 | XJar 是基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译,支持Spring Boot JAR 安全加密运行,同时支持的原生JAR。 8 | 更多文档请点击:[XJar](https://github.com/core-lib/xjar) 9 | 10 | ## 环境依赖 11 | JDK 1.7 + 12 | 13 | ## 集成步骤 14 | ```xml 15 | 16 | 17 | 18 | 19 | jitpack.io 20 | https://jitpack.io 21 | 22 | 23 | 24 | 25 | 26 | 27 | com.github.core-lib 28 | xjar-maven-plugin 29 | 4.0.2 30 | 31 | 32 | 33 | build 34 | 35 | package 36 | 37 | io.xjar 38 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | ``` 62 | #### 也可以通过Maven命令单独执行 XJar 插件 63 | ```text 64 | mvn xjar:build -Dxjar.password=io.xjar 65 | mvn xjar:build -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar 66 | ``` 67 | 68 | #### 但通常情况下是让XJar插件绑定到指定的phase中自动执行,这样就能在项目构建的时候自动构建出加密的包。 69 | ```text 70 | mvn clean package -Dxjar.password=io.xjar 71 | mvn clean install -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/target.xjar 72 | ``` 73 | 74 | ## 强烈建议 75 | 强烈建议不要在 pom.xml 的 xjar-maven-plugin 配置中写上密码,这样会导致打包出来的 xjar 包中的 pom.xml 文件保留着密码,极其容易暴露密码!强烈推荐通过 mvn 命令来指定加密密钥! 76 | 77 | ## 注意事项 78 | #### 不兼容 spring-boot-maven-plugin 的 executable = true 以及 embeddedLaunchScript 79 | ```xml 80 | 81 | org.springframework.boot 82 | spring-boot-maven-plugin 83 | 89 | 90 | ``` 91 | 92 | ## 参数说明 93 | | 参数名称 | 命令参数名称 | 参数说明 | 参数类型 | 缺省值 | 示例值 | 94 | | :------ | :----------- | :------ | :------ | :----- | :----- | 95 | | password | -Dxjar.password | 密码字符串 | String | 必须 | 任意字符串,io.xjar | 96 | | algorithm | -Dxjar.algorithm | 加密算法名称 | String | AES/CBC/PKCS5Padding | JDK内置加密算法,如:AES/CBC/PKCS5Padding 和 DES/CBC/PKCS5Padding | 97 | | keySize | -Dxjar.keySize | 密钥长度 | int | 128 | 根据加密算法而定,56,128,256 | 98 | | ivSize | -Dxjar.ivSize | 密钥向量长度 | int | 128 | 根据加密算法而定,128 | 99 | | sourceDir | -Dxjar.sourceDir | 源jar所在目录 | File | ${project.build.directory} | 文件目录 | 100 | | sourceJar | -Dxjar.sourceJar | 源jar名称 | String | ${project.build.finalName}.jar | 文件名称 | 101 | | targetDir | -Dxjar.targetDir | 目标jar存放目录 | File | ${project.build.directory} | 文件目录 | 102 | | targetJar | -Dxjar.targetJar | 目标jar名称 | String | ${project.build.finalName}.xjar | 文件名称 | 103 | | includes | -Dxjar.includes | 需要加密的资源路径表达式 | String[] | 无 | com/company/project/** , mapper/*Mapper.xml , 支持Ant表达式 | 104 | | excludes | -Dxjar.excludes | 无需加密的资源路径表达式 | String[] | 无 | static/** , META-INF/resources/** , 支持Ant表达式 | 105 | | deletes | -Dxjar.deletes | 加密后删除指定资源路径表达式 | String[] | 无 | target/\*.jar, ../module/target/\*.jar, 支持Ant表达式 | 106 | 107 | * 指定加密算法的时候密钥长度以及向量长度必须在算法可支持范围内, 具体加密算法的密钥及向量长度请自行百度或谷歌. 108 | * 当 includes 和 excludes 同时使用时即加密在includes的范围内且排除了excludes的资源。 109 | 110 | ## 版本记录 111 | * 4.0.2 112 | 1. 安全性升级 113 | * 4.0.1 114 | 1. 兼容JDK-9及以上版本 115 | * 4.0.0 116 | 1. 加解密支持填充模式 117 | 2. 加解密支持IV-Parameter 118 | 3. 升级启动器 119 | 4. 移除危险模式 120 | 5. 拼写错误修正 121 | 6. 提供智能加密/解密器 避免使用失误 122 | 7. 删除多余的加密/解密方法 123 | 8. 修复有安全校验的nested-lib在不加密其内部资源情况下启动时也无法通过校验的问题 124 | 9. 去除命令启动和手输密码启动的方式只保留Go启动器的模式 125 | 10. 增加可读性更强的Fluent风格的加密/解密API 126 | * 2.0.9 127 | * 修复XJar类加载器加载的类没有 ProtectionDomain 以及 CodeSource 的问题 128 | * 修复不同字符集机器间加密与运行的问题 129 | * 2.0.8 130 | * 版本号去除"v"前缀 131 | * v2.0.7 132 | * 支持加密后删除指定资源 133 | * v2.0.6 134 | * 解决多jar包启动时无法找到准确的MANIFEST.MF导致无法正常启动的问题 135 | * v2.0.5 136 | * 升级[LoadKit](https://github.com/core-lib/loadkit)依赖版本 137 | * 修复ANT表达式无法正确匹配**/*通配符的问题 138 | * v2.0.4 139 | * 解决危险模式不支持ubuntu系统的问题 140 | * v2.0.3 141 | * 过滤器泛型协变支持 142 | * 支持 includes 与 excludes 同时起效,当同时设置时即加密在includes范围内但又不在excludes范围内的资源 143 | * v2.0.2 144 | * 原生jar增加密钥文件的启动方式,解决类似 nohup 和 javaw 的后台启动方式无法通过控制台输入密码的问题 145 | * v2.0.1 146 | * 增加密钥文件的启动方式,解决类似 nohup 和 javaw 的后台启动方式无法通过控制台输入密码的问题 147 | * 修复解密后没有删除危险模式中在MANIFEST.MF中保留的密钥信息 148 | * v2.0.0 149 | * 升级为v2.0.0 与 xjar版本保持一致 150 | * v1.1.0 151 | * 支持 Spring-Boot 以ZIP方式打包,即依赖外部化方式启动。 152 | * 修复无加密资源时无法启动问题 153 | * v1.0.9 154 | * 支持危险模式加密,实现免密码启动,但是请谨慎使用! 155 | * v1.0.8 156 | * 避免过滤器使用不当造成无法启动 157 | * v1.0.7 158 | * bug修复 159 | * v1.0.6 160 | * 将对普通jar项目或模块和spring boot项目或模块的插件方式加密整合成一个智能分析goal,配置时无需关心当前项目或模块是哪一种。 161 | * 对于无法加密的Jar进行友好提示 162 | * 升级 XJar 版本为 v1.1.0 163 | * v1.0.5 164 | * 引用新版本的XJar(v1.0.9),修复不同版本的Spring-Boot加密无法运行问题 165 | * v1.0.4 166 | * 第一个正式版发布 167 | 168 | ## 协议声明 169 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) 170 | 171 | ## 加入群聊 172 | QQ 950956093 [![](https://pub.idqqimg.com/wpa/images/group.png)](https://shang.qq.com/wpa/qunwpa?idkey=e567db1c32de4b02da480d895566757b3df73e3f8827ed6c9149e2859e4cdc93) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.github.core-lib 5 | xjar-maven-plugin 6 | maven-plugin 7 | 4.0.2 8 | XJar Maven Plugin 9 | XJar Maven Plugin 10 | https://github.com/core-lib/xjar-maven-plugin 11 | 12 | 13 | UTF-8 14 | 1.7 15 | 1.7 16 | 17 | 18 | 19 | 20 | jitpack.io 21 | https://jitpack.io 22 | 23 | 24 | 25 | 26 | 27 | org.apache.maven 28 | maven-plugin-api 29 | 3.5.0 30 | 31 | 32 | org.apache.maven.plugin-tools 33 | maven-plugin-annotations 34 | 3.5 35 | provided 36 | 37 | 38 | com.github.core-lib 39 | xjar 40 | 4.0.2 41 | 42 | 43 | org.apache.maven 44 | maven-core 45 | 3.1.1 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-compiler-plugin 54 | 3.5.1 55 | 56 | 1.7 57 | 1.7 58 | true 59 | true 60 | UTF-8 61 | 62 | 63 | ${project.basedir}/src/main/java 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-source-plugin 71 | 3.0.1 72 | 73 | true 74 | 75 | 76 | 77 | compile 78 | 79 | jar 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/main/java/io/xjar/XAntEntryFilter.java: -------------------------------------------------------------------------------- 1 | package io.xjar; 2 | 3 | import org.apache.commons.compress.archivers.jar.JarArchiveEntry; 4 | 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * Ant表达式过滤器 9 | * 10 | * @author Payne 646742615@qq.com 11 | * 2018/12/4 14:16 12 | */ 13 | public abstract class XAntEntryFilter implements XEntryFilter { 14 | private static final String[] SYMBOLS = {"\\", "$", "(", ")", "+", ".", "[", "]", "^", "{", "}", "|"}; 15 | private final Pattern pattern; 16 | 17 | protected XAntEntryFilter(String ant) { 18 | String regex = ant; 19 | for (String symbol : SYMBOLS) regex = regex.replace(symbol, '\\' + symbol); 20 | regex = regex.replace("?", ".{1}"); 21 | regex = regex.replace("**/", "(.{0,}?/){0,}?"); 22 | regex = regex.replace("**", ".{0,}?"); 23 | regex = regex.replace("*", "[^/]{0,}?"); 24 | while (regex.startsWith("/")) regex = regex.substring(1); 25 | while (regex.endsWith("/")) regex = regex.substring(0, regex.length() - 1); 26 | this.pattern = Pattern.compile(regex); 27 | } 28 | 29 | protected boolean matches(String text) { 30 | return pattern.matcher(text).matches(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/xjar/XArray.java: -------------------------------------------------------------------------------- 1 | package io.xjar; 2 | 3 | /** 4 | * 数组工具 5 | * 6 | * @author Payne 646742615@qq.com 7 | * 2019/5/20 10:25 8 | */ 9 | public class XArray { 10 | 11 | /** 12 | * 数组是否为{@code null}或者是空数组 13 | * 14 | * @param array 数组 15 | * @return 如果是则返回{@code true} 否则返回{@code false} 16 | */ 17 | public static boolean isEmpty(Object[] array) { 18 | return array == null || array.length == 0; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/xjar/XBuilder.java: -------------------------------------------------------------------------------- 1 | package io.xjar; 2 | 3 | import io.loadkit.Loaders; 4 | import io.loadkit.Resource; 5 | import io.xjar.boot.XBoot; 6 | import io.xjar.filter.XAllEntryFilter; 7 | import io.xjar.filter.XAnyEntryFilter; 8 | import io.xjar.filter.XMixEntryFilter; 9 | import io.xjar.jar.XJar; 10 | import org.apache.commons.compress.archivers.jar.JarArchiveEntry; 11 | import org.apache.maven.model.Build; 12 | import org.apache.maven.model.Plugin; 13 | import org.apache.maven.plugin.AbstractMojo; 14 | import org.apache.maven.plugin.MojoExecutionException; 15 | import org.apache.maven.plugin.MojoFailureException; 16 | import org.apache.maven.plugin.logging.Log; 17 | import org.apache.maven.plugins.annotations.LifecyclePhase; 18 | import org.apache.maven.plugins.annotations.Mojo; 19 | import org.apache.maven.plugins.annotations.Parameter; 20 | import org.apache.maven.project.MavenProject; 21 | import org.codehaus.plexus.util.xml.Xpp3Dom; 22 | 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.net.URL; 26 | import java.util.Enumeration; 27 | import java.util.Map; 28 | 29 | /** 30 | * XJar 构建插件 31 | * 32 | * @author Payne 646742615@qq.com 33 | * 2018/12/4 10:27 34 | */ 35 | @Mojo(name = "build", defaultPhase = LifecyclePhase.PACKAGE) 36 | public class XBuilder extends AbstractMojo { 37 | /** 38 | * 当前Maven工程 39 | */ 40 | @Parameter(defaultValue = "${project}", readonly = true, required = true) 41 | private MavenProject project; 42 | 43 | /** 44 | * 加密算法名称 45 | */ 46 | @Parameter(property = "xjar.algorithm", required = true, defaultValue = "AES/CBC/PKCS5Padding") 47 | private String algorithm; 48 | 49 | /** 50 | * 加密密钥长度 51 | */ 52 | @Parameter(property = "xjar.keySize", required = true, defaultValue = "128") 53 | private int keySize; 54 | 55 | /** 56 | * 加密向量长度 57 | */ 58 | @Parameter(property = "xjar.ivSize", required = true, defaultValue = "128") 59 | private int ivSize; 60 | 61 | /** 62 | * 加密密码 63 | */ 64 | @Parameter(property = "xjar.password", required = true) 65 | private String password; 66 | 67 | /** 68 | * 原本JAR所在文件夹 69 | */ 70 | @Parameter(property = "xjar.sourceDir", required = true, defaultValue = "${project.build.directory}") 71 | private File sourceDir; 72 | 73 | /** 74 | * 原本JAR名称 75 | */ 76 | @Parameter(property = "xjar.sourceJar", required = true, defaultValue = "${project.build.finalName}.jar") 77 | private String sourceJar; 78 | 79 | /** 80 | * 生成JAR所在文件夹 81 | */ 82 | @Parameter(property = "xjar.targetDir", required = true, defaultValue = "${project.build.directory}") 83 | private File targetDir; 84 | 85 | /** 86 | * 生成JAR名称 87 | */ 88 | @Parameter(property = "xjar.targetJar", required = true, defaultValue = "${project.build.finalName}.xjar") 89 | private String targetJar; 90 | 91 | /** 92 | * 包含资源。 93 | * 使用Ant表达式,例如: 94 | * io/xjar/** 95 | * com/company/project/** 96 | * mapper/*Mapper.xml 97 | */ 98 | @Parameter(property = "xjar.includes") 99 | private String[] includes; 100 | 101 | /** 102 | * 排除资源。 103 | * 使用Ant表达式,例如: 104 | * io/xjar/** 105 | * static/** 106 | * META-INF/resources/** 107 | */ 108 | @Parameter(property = "xjar.excludes") 109 | private String[] excludes; 110 | 111 | /** 112 | * 加密完成后需要删除的资源 113 | * 支持Ant表达式,例如: 114 | * target/*.jar 115 | * ../module/target/*.jar 116 | */ 117 | @Parameter(property = "xjar.deletes") 118 | private String[] deletes; 119 | 120 | @Override 121 | public void execute() throws MojoExecutionException, MojoFailureException { 122 | Log log = getLog(); 123 | String packaging = project.getPackaging(); 124 | if (!"jar".equalsIgnoreCase(packaging)) { 125 | log.info("Skip for packaging: " + packaging); 126 | return; 127 | } 128 | try { 129 | if (log.isDebugEnabled()) { 130 | log.debug("Using algorithm: " + algorithm); 131 | log.debug("Using key-size: " + keySize); 132 | log.debug("Using iv-size: " + ivSize); 133 | log.debug("Using password: " + password); 134 | } 135 | File src = new File(sourceDir, sourceJar); 136 | File dest = new File(targetDir, targetJar); 137 | File folder = dest.getParentFile(); 138 | if (!folder.exists() && !folder.mkdirs() && !folder.exists()) { 139 | throw new IOException("could not make directory: " + folder); 140 | } 141 | log.info("Building xjar: " + dest + " for jar: " + src); 142 | 143 | XMixEntryFilter filter; 144 | if (XArray.isEmpty(includes) && XArray.isEmpty(excludes)) { 145 | filter = null; 146 | log.info("Including all resources"); 147 | } else { 148 | filter = XKit.all(); 149 | if (!XArray.isEmpty(includes)) { 150 | XAnyEntryFilter including = XKit.any(); 151 | for (String include : includes) { 152 | including.mix(new XIncludeAntEntryFilter(include)); 153 | log.info("Including " + include); 154 | } 155 | filter.mix(including); 156 | } 157 | if (!XArray.isEmpty(excludes)) { 158 | XAllEntryFilter excluding = XKit.all(); 159 | for (String exclude : excludes) { 160 | excluding.mix(new XExcludeAntEntryFilter(exclude)); 161 | log.info("Excluding " + exclude); 162 | } 163 | filter.mix(excluding); 164 | } 165 | } 166 | 167 | Build build = project.getBuild(); 168 | Map plugins = build.getPluginsAsMap(); 169 | Plugin plugin = plugins.get("org.springframework.boot:spring-boot-maven-plugin"); 170 | // 非Spring-Boot项目/模块 171 | if (plugin == null) { 172 | XJar.encrypt(src, dest, XKit.key(algorithm, keySize, ivSize, password), filter); 173 | } 174 | // Spring-Boot项目/模块 175 | else { 176 | Object configuration = plugin.getConfiguration(); 177 | // 不允许开启 true 178 | if (configuration instanceof Xpp3Dom) { 179 | Xpp3Dom dom = (Xpp3Dom) configuration; 180 | { 181 | Xpp3Dom child = dom.getChild("executable"); 182 | String executable = child != null ? child.getValue() : null; 183 | if ("true".equalsIgnoreCase(executable)) { 184 | String msg = "Unsupported to build an xjar for an true spring boot JAR file, "; 185 | msg += "maybe you should upgrade xjar-maven-plugin dependency if it have been supported in the later versions,"; 186 | msg += "if not, delete true or set executable as false for the configuration of spring-boot-maven-plugin."; 187 | throw new MojoFailureException(msg); 188 | } 189 | } 190 | { 191 | Xpp3Dom child = dom.getChild("embeddedLaunchScript"); 192 | String embeddedLaunchScript = child != null ? child.getValue() : null; 193 | if (embeddedLaunchScript != null) { 194 | String msg = "Unsupported to build an xjar for an ... spring boot JAR file, "; 195 | msg += "maybe you should upgrade xjar-maven-plugin dependency if it have been supported in the later versions,"; 196 | msg += "if not, delete ... for the configuration of spring-boot-maven-plugin."; 197 | throw new MojoFailureException(msg); 198 | } 199 | } 200 | } 201 | XBoot.encrypt(src, dest, XKit.key(algorithm, keySize, ivSize, password), filter); 202 | } 203 | 204 | File root = project.getFile().getParentFile(); 205 | for (int i = 0; deletes != null && i < deletes.length; i++) { 206 | String delete = deletes[i]; 207 | File dir = root; 208 | while (delete.startsWith("../")) { 209 | dir = dir.getParentFile() != null ? dir.getParentFile() : dir; 210 | delete = delete.substring("../".length()); 211 | } 212 | 213 | log.info("Deleting file(s) matching pattern: " + dir.getCanonicalPath().replace('\\', '/') + "/" + delete); 214 | 215 | Enumeration resources = Loaders.ant(Loaders.file(dir)).load(delete); 216 | while (resources.hasMoreElements()) { 217 | Resource resource = resources.nextElement(); 218 | URL url = resource.getUrl(); 219 | String path = url.getPath(); 220 | File file = new File(path); 221 | log.debug("Deleting file: " + file.getCanonicalPath()); 222 | if (!file.delete()) { 223 | log.warn("Could not delete file: " + file); 224 | } 225 | } 226 | } 227 | 228 | } catch (MojoExecutionException | MojoFailureException e) { 229 | throw e; 230 | } catch (Exception e) { 231 | throw new MojoExecutionException("could not build xjar", e); 232 | } 233 | } 234 | 235 | public MavenProject getProject() { 236 | return project; 237 | } 238 | 239 | public void setProject(MavenProject project) { 240 | this.project = project; 241 | } 242 | 243 | public String getAlgorithm() { 244 | return algorithm; 245 | } 246 | 247 | public void setAlgorithm(String algorithm) { 248 | this.algorithm = algorithm; 249 | } 250 | 251 | public int getKeySize() { 252 | return keySize; 253 | } 254 | 255 | public void setKeySize(int keySize) { 256 | this.keySize = keySize; 257 | } 258 | 259 | public int getIvSize() { 260 | return ivSize; 261 | } 262 | 263 | public void setIvSize(int ivSize) { 264 | this.ivSize = ivSize; 265 | } 266 | 267 | public String getPassword() { 268 | return password; 269 | } 270 | 271 | public void setPassword(String password) { 272 | this.password = password; 273 | } 274 | 275 | public File getSourceDir() { 276 | return sourceDir; 277 | } 278 | 279 | public void setSourceDir(File sourceDir) { 280 | this.sourceDir = sourceDir; 281 | } 282 | 283 | public String getSourceJar() { 284 | return sourceJar; 285 | } 286 | 287 | public void setSourceJar(String sourceJar) { 288 | this.sourceJar = sourceJar; 289 | } 290 | 291 | public File getTargetDir() { 292 | return targetDir; 293 | } 294 | 295 | public void setTargetDir(File targetDir) { 296 | this.targetDir = targetDir; 297 | } 298 | 299 | public String getTargetJar() { 300 | return targetJar; 301 | } 302 | 303 | public void setTargetJar(String targetJar) { 304 | this.targetJar = targetJar; 305 | } 306 | 307 | public String[] getIncludes() { 308 | return includes; 309 | } 310 | 311 | public void setIncludes(String[] includes) { 312 | this.includes = includes; 313 | } 314 | 315 | public String[] getExcludes() { 316 | return excludes; 317 | } 318 | 319 | public void setExcludes(String[] excludes) { 320 | this.excludes = excludes; 321 | } 322 | 323 | public String[] getDeletes() { 324 | return deletes; 325 | } 326 | 327 | public void setDeletes(String[] deletes) { 328 | this.deletes = deletes; 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /src/main/java/io/xjar/XExcludeAntEntryFilter.java: -------------------------------------------------------------------------------- 1 | package io.xjar; 2 | 3 | import org.apache.commons.compress.archivers.jar.JarArchiveEntry; 4 | 5 | /** 6 | * 排除过滤器 7 | * 8 | * @author Payne 646742615@qq.com 9 | * 2018/12/4 14:10 10 | */ 11 | public class XExcludeAntEntryFilter extends XAntEntryFilter implements XEntryFilter { 12 | 13 | public XExcludeAntEntryFilter(String ant) { 14 | super(ant); 15 | } 16 | 17 | @Override 18 | public boolean filtrate(JarArchiveEntry entry) { 19 | return !matches(entry.getName()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/xjar/XIncludeAntEntryFilter.java: -------------------------------------------------------------------------------- 1 | package io.xjar; 2 | 3 | import org.apache.commons.compress.archivers.jar.JarArchiveEntry; 4 | 5 | /** 6 | * 包含过滤器 7 | * 8 | * @author Payne 646742615@qq.com 9 | * 2018/12/4 14:10 10 | */ 11 | public class XIncludeAntEntryFilter extends XAntEntryFilter implements XEntryFilter { 12 | 13 | public XIncludeAntEntryFilter(String ant) { 14 | super(ant); 15 | } 16 | 17 | @Override 18 | public boolean filtrate(JarArchiveEntry entry) { 19 | return matches(entry.getName()); 20 | } 21 | } 22 | --------------------------------------------------------------------------------