├── .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 |
--------------------------------------------------------------------------------