├── .drone.yml ├── .github └── workflows │ └── maven-publish.yml ├── .gitignore ├── README.md ├── pom.xml └── src └── main └── java └── dev └── mdma └── qprotect └── ObfuscationMojo.java /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | type: docker 3 | name: default 4 | steps: 5 | - name: discord start notification 6 | image: appleboy/drone-discord 7 | settings: 8 | avatar_url: 'https://mdma.dev/data/assets/logo/512.png' 9 | color: blue 10 | username: qTechnologies CI 11 | webhook_id: 12 | from_secret: discord_webhook_id 13 | webhook_token: 14 | from_secret: discord_webhook_token 15 | message: > 16 | {{repo.name}} build {{build.number}} has started. 17 | - name: authenticate 18 | image: robertstettner/drone-mvn-auth 19 | volumes: 20 | - name: cache 21 | path: /root/.m2 22 | - name: build 23 | image: 'maven:3.8.4-jdk-8' 24 | volumes: 25 | - name: cache 26 | path: /root/.m2 27 | commands: 28 | - export M2_HOME=/usr/share/maven 29 | - mvn package -gs settings.xml 30 | - name: discord-notify 31 | image: brazildatacube/bdc-drone-discord 32 | settings: 33 | webhook: 34 | from_secret: webhook_url 35 | when: 36 | status: 37 | - failure 38 | - success 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/maven-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created 2 | # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path 3 | 4 | name: Maven Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: read 16 | packages: write 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Set up JDK 11 21 | uses: actions/setup-java@v3 22 | with: 23 | java-version: '11' 24 | distribution: 'temurin' 25 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 26 | settings-path: ${{ github.workspace }} # location for the settings.xml file 27 | 28 | - name: Build with Maven 29 | run: mvn -B package --file pom.xml 30 | 31 | - name: Publish to GitHub Packages Apache Maven 32 | run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml 33 | env: 34 | GITHUB_TOKEN: ${{ github.token }} 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/java,intellij+all,maven,git 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=java,intellij+all,maven,git 4 | 5 | ### Git ### 6 | # Created by git for backups. To disable backups in Git: 7 | # $ git config --global mergetool.keepBackup false 8 | *.orig 9 | 10 | # Created by git when using merge tools for conflicts 11 | *.BACKUP.* 12 | *.BASE.* 13 | *.LOCAL.* 14 | *.REMOTE.* 15 | *_BACKUP_*.txt 16 | *_BASE_*.txt 17 | *_LOCAL_*.txt 18 | *_REMOTE_*.txt 19 | 20 | ### Intellij+all ### 21 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 22 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 23 | 24 | # User-specific stuff 25 | .idea/**/workspace.xml 26 | .idea/**/tasks.xml 27 | .idea/**/usage.statistics.xml 28 | .idea/**/dictionaries 29 | .idea/**/shelf 30 | 31 | # Generated files 32 | .idea/**/contentModel.xml 33 | 34 | # Sensitive or high-churn files 35 | .idea/**/dataSources/ 36 | .idea/**/dataSources.ids 37 | .idea/**/dataSources.local.xml 38 | .idea/**/sqlDataSources.xml 39 | .idea/**/dynamic.xml 40 | .idea/**/uiDesigner.xml 41 | .idea/**/dbnavigator.xml 42 | 43 | # Gradle 44 | .idea/**/gradle.xml 45 | .idea/**/libraries 46 | 47 | # Gradle and Maven with auto-import 48 | # When using Gradle or Maven with auto-import, you should exclude module files, 49 | # since they will be recreated, and may cause churn. Uncomment if using 50 | # auto-import. 51 | # .idea/artifacts 52 | # .idea/compiler.xml 53 | # .idea/jarRepositories.xml 54 | # .idea/modules.xml 55 | # .idea/*.iml 56 | # .idea/modules 57 | # *.iml 58 | # *.ipr 59 | 60 | # CMake 61 | cmake-build-*/ 62 | 63 | # Mongo Explorer plugin 64 | .idea/**/mongoSettings.xml 65 | 66 | # File-based project format 67 | *.iws 68 | 69 | # IntelliJ 70 | out/ 71 | 72 | # mpeltonen/sbt-idea plugin 73 | .idea_modules/ 74 | 75 | # JIRA plugin 76 | atlassian-ide-plugin.xml 77 | 78 | # Cursive Clojure plugin 79 | .idea/replstate.xml 80 | 81 | # Crashlytics plugin (for Android Studio and IntelliJ) 82 | com_crashlytics_export_strings.xml 83 | crashlytics.properties 84 | crashlytics-build.properties 85 | fabric.properties 86 | 87 | # Editor-based Rest Client 88 | .idea/httpRequests 89 | 90 | # Android studio 3.1+ serialized cache file 91 | .idea/caches/build_file_checksums.ser 92 | 93 | ### Intellij+all Patch ### 94 | # Ignores the whole .idea folder and all .iml files 95 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 96 | 97 | .idea/ 98 | 99 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 100 | 101 | *.iml 102 | modules.xml 103 | .idea/misc.xml 104 | *.ipr 105 | 106 | # Sonarlint plugin 107 | .idea/sonarlint 108 | 109 | ### Java ### 110 | # Compiled class file 111 | *.class 112 | 113 | # Log file 114 | *.log 115 | 116 | # BlueJ files 117 | *.ctxt 118 | 119 | # Mobile Tools for Java (J2ME) 120 | .mtj.tmp/ 121 | 122 | # Package Files # 123 | *.jar 124 | *.war 125 | *.nar 126 | *.ear 127 | *.zip 128 | *.tar.gz 129 | *.rar 130 | 131 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 132 | hs_err_pid* 133 | 134 | ### Maven ### 135 | target/ 136 | pom.xml.tag 137 | pom.xml.releaseBackup 138 | pom.xml.versionsBackup 139 | pom.xml.next 140 | release.properties 141 | dependency-reduced-pom.xml 142 | buildNumber.properties 143 | .mvn/timing.properties 144 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 145 | .mvn/wrapper/maven-wrapper.jar 146 | 147 | # End of https://www.toptal.com/developers/gitignore/api/java,intellij+all,maven,git 148 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # obfuscation-maven-plugin 3 | A maven plugin used to obfuscate a compiled file with qProtect and qProtect Lite 4 | 5 | ## Instructions 6 | - add our repository as pluginRepository 7 | 8 | ```xml 9 | 10 | 11 | nexus-releases 12 | https://nexus.mdma.dev/repository/maven-releases/ 13 | 14 | 15 | ``` 16 | 17 | - add our plugin into your maven build 18 | 19 | ```xml 20 | 21 | dev.mdma.qprotect 22 | obfuscation-maven-plugin 23 | 1.0.3 24 | 25 | C:\qprotect-core-1.10.8.jar 26 | ${project.basedir}/config.yml 27 | 28 | ${project.basedir}/target/test-1.0.jar 29 | ${project.basedir}/target/test-1.0-obf.jar 30 | 31 | C:\Program Files\Java\jdk-1.8 32 | 33 | 34 | 35 | 36 | obfuscate 37 | 38 | 39 | 40 | 41 | ``` 42 | - set the qprotect and the input, output and config path 43 | - then build your project using maven package 44 | 45 | 46 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | dev.mdma.qprotect 8 | obfuscation-maven-plugin 9 | maven-plugin 10 | https://mdma.dev 11 | 1.0.4 12 | 13 | 14 | UTF-8 15 | 8 16 | 8 17 | 3.9.6 18 | 3.10.2 19 | 20 | 21 | 22 | 23 | org.apache.maven 24 | maven-plugin-api 25 | ${mavenVersion} 26 | provided 27 | 28 | 29 | org.apache.maven 30 | maven-core 31 | ${mavenVersion} 32 | provided 33 | 34 | 35 | org.apache.maven.plugin-tools 36 | maven-plugin-annotations 37 | ${pluginToolsVersion} 38 | provided 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/dev/mdma/qprotect/ObfuscationMojo.java: -------------------------------------------------------------------------------- 1 | package dev.mdma.qprotect; 2 | 3 | import org.apache.maven.plugin.AbstractMojo; 4 | import org.apache.maven.plugin.MojoExecutionException; 5 | import org.apache.maven.plugins.annotations.LifecyclePhase; 6 | import org.apache.maven.plugins.annotations.Mojo; 7 | import org.apache.maven.plugins.annotations.Parameter; 8 | import org.apache.maven.plugins.annotations.ResolutionScope; 9 | import org.apache.maven.project.MavenProject; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.io.InputStreamReader; 15 | import java.util.Objects; 16 | 17 | @Mojo(name = "obfuscate", 18 | defaultPhase = LifecyclePhase.PACKAGE, 19 | requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) 20 | public class ObfuscationMojo extends AbstractMojo { 21 | 22 | @Parameter(property = "obfuscation.skip", defaultValue = "false") 23 | private boolean isSkip; 24 | 25 | @Parameter(property = "obfuscation.path", required = true) 26 | private File obfuscatorPath; 27 | 28 | @Parameter(property = "obfuscation.configFile", required = true) 29 | private File configFile; 30 | 31 | @Parameter(property = "obfuscation.inputFile") 32 | private File inputFile; 33 | 34 | @Parameter(property = "obfuscation.outputFile") 35 | private File outputFile; 36 | 37 | @Parameter(property = "obfuscation.javaPath") 38 | private File javaPath; 39 | 40 | @Parameter(property = "project", readonly = true, required = true) 41 | protected MavenProject mavenProject; 42 | 43 | @Override 44 | public void execute() throws MojoExecutionException { 45 | if (isSkip) { 46 | getLog().info("Skipping qProtect obfuscation because isSkip is set to 'true'"); 47 | return; 48 | } 49 | 50 | if (obfuscatorPath == null || !obfuscatorPath.exists()) { 51 | throw new MojoExecutionException("qProtect Obfuscator Path is null or does not exist."); 52 | } 53 | 54 | if (configFile == null || !configFile.exists()) { 55 | throw new MojoExecutionException("qProtect Obfuscator Config Path is null or does not exist."); 56 | } 57 | 58 | if(Objects.nonNull(javaPath)) 59 | System.out.println("Using custom java path " + javaPath); 60 | 61 | try { 62 | Process process = createProecess(); 63 | 64 | // Capture the log 65 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { 66 | String line; 67 | while ((line = reader.readLine()) != null) { 68 | getLog().info(line); 69 | } 70 | } 71 | 72 | int exitCode = process.waitFor(); 73 | 74 | if (exitCode != 0) { 75 | throw new MojoExecutionException("qProtect failed with exit code: " + exitCode); 76 | } 77 | } catch (IOException | InterruptedException e) { 78 | throw new MojoExecutionException("An exception occurred while running the qProtect process.", e); 79 | } 80 | } 81 | 82 | private Process createProecess() throws IOException { 83 | ProcessBuilder processBuilder = new ProcessBuilder( 84 | Objects.isNull(javaPath) ? "java" : javaPath + File.separator + "bin" + File.separator + "java", 85 | "-jar", 86 | obfuscatorPath.getAbsolutePath(), 87 | "--config", 88 | configFile.getAbsolutePath() 89 | ); 90 | 91 | if (inputFile != null) { 92 | processBuilder.command().add("--input"); 93 | processBuilder.command().add(inputFile.getAbsolutePath()); 94 | } 95 | 96 | if (outputFile != null) { 97 | processBuilder.command().add("--output"); 98 | processBuilder.command().add(outputFile.getAbsolutePath()); 99 | } 100 | 101 | processBuilder.redirectErrorStream(true); 102 | Process process = processBuilder.start(); 103 | return process; 104 | } 105 | } 106 | --------------------------------------------------------------------------------