mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Add stack deobfuscation to dev server
This commit is contained in:
parent
68522811f2
commit
78c55437e3
|
@ -10,6 +10,7 @@
|
||||||
</option>
|
</option>
|
||||||
<option name="goals">
|
<option name="goals">
|
||||||
<list>
|
<list>
|
||||||
|
<option value="-e" />
|
||||||
<option value="install" />
|
<option value="install" />
|
||||||
<option value="-DskipTests" />
|
<option value="-DskipTests" />
|
||||||
<option value="-Dteavm.build.all=false" />
|
<option value="-Dteavm.build.all=false" />
|
||||||
|
|
|
@ -490,6 +490,7 @@ public class Renderer implements RenderingManager {
|
||||||
writer.append(',').softNewLine();
|
writer.append(',').softNewLine();
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
debugEmitter.emitClass(cls.getName());
|
||||||
writer.appendClass(cls.getName()).append(",").ws();
|
writer.appendClass(cls.getName()).append(",").ws();
|
||||||
|
|
||||||
if (classesRequiringName.contains(cls.getName())) {
|
if (classesRequiringName.contains(cls.getName())) {
|
||||||
|
@ -541,6 +542,7 @@ public class Renderer implements RenderingManager {
|
||||||
collectMethodsToCopyFromInterfaces(classSource.get(cls.getName()), virtualMethods);
|
collectMethodsToCopyFromInterfaces(classSource.get(cls.getName()), virtualMethods);
|
||||||
|
|
||||||
renderVirtualDeclarations(virtualMethods);
|
renderVirtualDeclarations(virtualMethods);
|
||||||
|
debugEmitter.emitClass(null);
|
||||||
}
|
}
|
||||||
writer.append("]);").newLine();
|
writer.append("]);").newLine();
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,10 @@ public final class TeaVMDevServerRunner {
|
||||||
.withDescription("display indicator on web page")
|
.withDescription("display indicator on web page")
|
||||||
.withLongOpt("indicator")
|
.withLongOpt("indicator")
|
||||||
.create('i'));
|
.create('i'));
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withDescription("deobfuscate stack traces")
|
||||||
|
.withLongOpt("deobfuscate-stack")
|
||||||
|
.create());
|
||||||
options.addOption(OptionBuilder
|
options.addOption(OptionBuilder
|
||||||
.withDescription("automatically reload page when compilation completes")
|
.withDescription("automatically reload page when compilation completes")
|
||||||
.withLongOpt("auto-reload")
|
.withLongOpt("auto-reload")
|
||||||
|
@ -123,6 +127,7 @@ public final class TeaVMDevServerRunner {
|
||||||
parseOutputOptions();
|
parseOutputOptions();
|
||||||
|
|
||||||
devServer.setIndicator(commandLine.hasOption("indicator"));
|
devServer.setIndicator(commandLine.hasOption("indicator"));
|
||||||
|
devServer.setDeobfuscateStack(commandLine.hasOption("deobfuscate-stack"));
|
||||||
devServer.setReloadedAutomatically(commandLine.hasOption("auto-reload"));
|
devServer.setReloadedAutomatically(commandLine.hasOption("auto-reload"));
|
||||||
devServer.setLog(new ConsoleTeaVMToolLog(commandLine.hasOption('v')));
|
devServer.setLog(new ConsoleTeaVMToolLog(commandLine.hasOption('v')));
|
||||||
if (commandLine.hasOption("port")) {
|
if (commandLine.hasOption("port")) {
|
||||||
|
|
|
@ -122,6 +122,12 @@ public final class TeaVMRunner {
|
||||||
.hasArg()
|
.hasArg()
|
||||||
.withDescription("WebAssembly binary version (currently, only 1 is supported)")
|
.withDescription("WebAssembly binary version (currently, only 1 is supported)")
|
||||||
.create());
|
.create());
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withLongOpt("entry-point")
|
||||||
|
.withArgName("name")
|
||||||
|
.hasArg()
|
||||||
|
.withDescription("Entry point name in target language (main by default)")
|
||||||
|
.create("e"));
|
||||||
options.addOption(OptionBuilder
|
options.addOption(OptionBuilder
|
||||||
.withLongOpt("min-heap")
|
.withLongOpt("min-heap")
|
||||||
.withArgName("size")
|
.withArgName("size")
|
||||||
|
@ -166,6 +172,10 @@ public final class TeaVMRunner {
|
||||||
parseWasmOptions();
|
parseWasmOptions();
|
||||||
parseHeap();
|
parseHeap();
|
||||||
|
|
||||||
|
if (commandLine.hasOption("e")) {
|
||||||
|
tool.setEntryPointName(commandLine.getOptionValue("e"));
|
||||||
|
}
|
||||||
|
|
||||||
interactive = commandLine.hasOption('w');
|
interactive = commandLine.hasOption('w');
|
||||||
|
|
||||||
String[] args = commandLine.getArgs();
|
String[] args = commandLine.getArgs();
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class TeaVMTool {
|
||||||
private String targetFileName = "";
|
private String targetFileName = "";
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
private String entryPointName = "main";
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
private boolean debugInformationGenerated;
|
private boolean debugInformationGenerated;
|
||||||
private boolean sourceMapsFileGenerated;
|
private boolean sourceMapsFileGenerated;
|
||||||
|
@ -139,6 +140,10 @@ public class TeaVMTool {
|
||||||
this.mainClass = mainClass;
|
this.mainClass = mainClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setEntryPointName(String entryPointName) {
|
||||||
|
this.entryPointName = entryPointName;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDebugInformationGenerated() {
|
public boolean isDebugInformationGenerated() {
|
||||||
return debugInformationGenerated;
|
return debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +372,7 @@ public class TeaVMTool {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
if (mainClass != null) {
|
if (mainClass != null) {
|
||||||
vm.entryPoint(mainClass);
|
vm.entryPoint(mainClass, entryPointName);
|
||||||
}
|
}
|
||||||
for (String className : classesToPreserve) {
|
for (String className : classesToPreserve) {
|
||||||
vm.preserveType(className);
|
vm.preserveType(className);
|
||||||
|
|
|
@ -38,6 +38,8 @@ public interface BuildStrategy {
|
||||||
|
|
||||||
void setMainClass(String mainClass);
|
void setMainClass(String mainClass);
|
||||||
|
|
||||||
|
void setEntryPointName(String entryPointName);
|
||||||
|
|
||||||
void setTargetDirectory(String targetDirectory);
|
void setTargetDirectory(String targetDirectory);
|
||||||
|
|
||||||
void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated);
|
void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated);
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
private List<String> classPathEntries = new ArrayList<>();
|
private List<String> classPathEntries = new ArrayList<>();
|
||||||
private TeaVMTargetType targetType;
|
private TeaVMTargetType targetType;
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
private String entryPointName;
|
||||||
private String targetDirectory;
|
private String targetDirectory;
|
||||||
private String targetFileName = "";
|
private String targetFileName = "";
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
|
@ -98,6 +99,11 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
this.mainClass = mainClass;
|
this.mainClass = mainClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEntryPointName(String entryPointName) {
|
||||||
|
this.entryPointName = entryPointName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTargetDirectory(String targetDirectory) {
|
public void setTargetDirectory(String targetDirectory) {
|
||||||
this.targetDirectory = targetDirectory;
|
this.targetDirectory = targetDirectory;
|
||||||
|
@ -191,6 +197,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
tool.setLog(log);
|
tool.setLog(log);
|
||||||
tool.setTargetType(targetType);
|
tool.setTargetType(targetType);
|
||||||
tool.setMainClass(mainClass);
|
tool.setMainClass(mainClass);
|
||||||
|
tool.setEntryPointName(entryPointName);
|
||||||
tool.setTargetDirectory(new File(targetDirectory));
|
tool.setTargetDirectory(new File(targetDirectory));
|
||||||
tool.setTargetFileName(targetFileName);
|
tool.setTargetFileName(targetFileName);
|
||||||
tool.setClassLoader(buildClassLoader());
|
tool.setClassLoader(buildClassLoader());
|
||||||
|
|
|
@ -78,6 +78,11 @@ public class RemoteBuildStrategy implements BuildStrategy {
|
||||||
request.mainClass = mainClass;
|
request.mainClass = mainClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEntryPointName(String entryPointName) {
|
||||||
|
request.entryPointName = entryPointName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTargetDirectory(String targetDirectory) {
|
public void setTargetDirectory(String targetDirectory) {
|
||||||
request.targetDirectory = targetDirectory;
|
request.targetDirectory = targetDirectory;
|
||||||
|
@ -219,7 +224,7 @@ public class RemoteBuildStrategy implements BuildStrategy {
|
||||||
private TeaVMProgressListener listener;
|
private TeaVMProgressListener listener;
|
||||||
private TeaVMToolLog log;
|
private TeaVMToolLog log;
|
||||||
|
|
||||||
public CallbackImpl(TeaVMProgressListener listener, TeaVMToolLog log) throws RemoteException {
|
CallbackImpl(TeaVMProgressListener listener, TeaVMToolLog log) throws RemoteException {
|
||||||
super();
|
super();
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
|
|
@ -141,6 +141,7 @@ public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildServi
|
||||||
}
|
}
|
||||||
tool.setTargetType(request.targetType);
|
tool.setTargetType(request.targetType);
|
||||||
tool.setMainClass(request.mainClass);
|
tool.setMainClass(request.mainClass);
|
||||||
|
tool.setEntryPointName(request.entryPointName);
|
||||||
tool.setTargetDirectory(new File(request.targetDirectory));
|
tool.setTargetDirectory(new File(request.targetDirectory));
|
||||||
tool.setTargetFileName(request.tagetFileName);
|
tool.setTargetFileName(request.tagetFileName);
|
||||||
tool.setClassLoader(buildClassLoader(request.classPath, incremental && request.incremental));
|
tool.setClassLoader(buildClassLoader(request.classPath, incremental && request.incremental));
|
||||||
|
|
|
@ -31,6 +31,7 @@ public class RemoteBuildRequest implements Serializable {
|
||||||
public String[] classesToPreserve;
|
public String[] classesToPreserve;
|
||||||
public TeaVMTargetType targetType;
|
public TeaVMTargetType targetType;
|
||||||
public String mainClass;
|
public String mainClass;
|
||||||
|
public String entryPointName;
|
||||||
public String targetDirectory;
|
public String targetDirectory;
|
||||||
public String tagetFileName = "";
|
public String tagetFileName = "";
|
||||||
public boolean sourceMapsFileGenerated;
|
public boolean sourceMapsFileGenerated;
|
||||||
|
|
|
@ -61,6 +61,12 @@
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-jso-apis</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-tooling</artifactId>
|
<artifactId>teavm-tooling</artifactId>
|
||||||
|
@ -100,6 +106,41 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-maven-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-jso-impl</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-classlib</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile-deobfuscator</id>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>process-classes</phase>
|
||||||
|
<configuration>
|
||||||
|
<targetDirectory>${build.directory}/classes/teavm/devserver</targetDirectory>
|
||||||
|
<targetFileName>deobfuscator.js</targetFileName>
|
||||||
|
<minifying>true</minifying>
|
||||||
|
<optimizationLevel>ADVANCED</optimizationLevel>
|
||||||
|
<mainClass>org.teavm.devserver.deobfuscate.Deobfuscator</mainClass>
|
||||||
|
<entryPointName>$teavm_deobfuscator</entryPointName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
|
|
@ -97,9 +97,11 @@ public class CodeServlet extends HttpServlet {
|
||||||
private String fileName = "classes.js";
|
private String fileName = "classes.js";
|
||||||
private String pathToFile = "/";
|
private String pathToFile = "/";
|
||||||
private String indicatorWsPath;
|
private String indicatorWsPath;
|
||||||
|
private String deobfuscatorPath;
|
||||||
private List<String> sourcePath = new ArrayList<>();
|
private List<String> sourcePath = new ArrayList<>();
|
||||||
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
private boolean indicator;
|
private boolean indicator;
|
||||||
|
private boolean deobfuscateStack;
|
||||||
private boolean automaticallyReloaded;
|
private boolean automaticallyReloaded;
|
||||||
private int port;
|
private int port;
|
||||||
private int debugPort;
|
private int debugPort;
|
||||||
|
@ -163,6 +165,10 @@ public class CodeServlet extends HttpServlet {
|
||||||
this.indicator = indicator;
|
this.indicator = indicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDeobfuscateStack(boolean deobfuscateStack) {
|
||||||
|
this.deobfuscateStack = deobfuscateStack;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPort(int port) {
|
public void setPort(int port) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +269,7 @@ public class CodeServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
indicatorWsPath = pathToFile + fileName + ".ws";
|
indicatorWsPath = pathToFile + fileName + ".ws";
|
||||||
|
deobfuscatorPath = pathToFile + fileName + ".deobfuscator.js";
|
||||||
WebSocketPolicy wsPolicy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy wsPolicy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
wsFactory = WebSocketServletFactory.Loader.load(config.getServletContext(), wsPolicy);
|
wsFactory = WebSocketServletFactory.Loader.load(config.getServletContext(), wsPolicy);
|
||||||
wsFactory.setCreator((req, resp) -> {
|
wsFactory.setCreator((req, resp) -> {
|
||||||
|
@ -304,6 +311,9 @@ public class CodeServlet extends HttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (path.equals(deobfuscatorPath)) {
|
||||||
|
serveDeobfuscator(resp);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
byte[] fileContent;
|
byte[] fileContent;
|
||||||
boolean firstTime;
|
boolean firstTime;
|
||||||
|
@ -340,6 +350,17 @@ public class CodeServlet extends HttpServlet {
|
||||||
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void serveDeobfuscator(HttpServletResponse resp) throws IOException {
|
||||||
|
ClassLoader loader = CodeServlet.class.getClassLoader();
|
||||||
|
resp.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
resp.setCharacterEncoding("UTF-8");
|
||||||
|
resp.setContentType("text/plain");
|
||||||
|
try (InputStream input = loader.getResourceAsStream("teavm/devserver/deobfuscator.js")) {
|
||||||
|
IOUtils.copy(input, resp.getOutputStream());
|
||||||
|
}
|
||||||
|
resp.getOutputStream().flush();
|
||||||
|
}
|
||||||
|
|
||||||
private void proxy(HttpServletRequest req, HttpServletResponse resp, String path) throws IOException {
|
private void proxy(HttpServletRequest req, HttpServletResponse resp, String path) throws IOException {
|
||||||
AsyncContext async = req.startAsync();
|
AsyncContext async = req.startAsync();
|
||||||
|
|
||||||
|
@ -763,9 +784,11 @@ public class CodeServlet extends HttpServlet {
|
||||||
script = script.replace("WS_PATH", "localhost:" + port + pathToFile + fileName + ".ws");
|
script = script.replace("WS_PATH", "localhost:" + port + pathToFile + fileName + ".ws");
|
||||||
script = script.replace("BOOT_FLAG", Boolean.toString(boot));
|
script = script.replace("BOOT_FLAG", Boolean.toString(boot));
|
||||||
script = script.replace("RELOAD_FLAG", Boolean.toString(automaticallyReloaded));
|
script = script.replace("RELOAD_FLAG", Boolean.toString(automaticallyReloaded));
|
||||||
script = script.replace("FILE_NAME", "http://localhost:" + port + pathToFile + fileName);
|
|
||||||
script = script.replace("INDICATOR_FLAG", Boolean.toString(indicator));
|
script = script.replace("INDICATOR_FLAG", Boolean.toString(indicator));
|
||||||
script = script.replace("DEBUG_PORT", Integer.toString(debugPort));
|
script = script.replace("DEBUG_PORT", Integer.toString(debugPort));
|
||||||
|
script = script.replace("FILE_NAME", "\"" + fileName + "\"");
|
||||||
|
script = script.replace("PATH_TO_FILE", "\"http://localhost:" + port + pathToFile + "\"");
|
||||||
|
script = script.replace("DEOBFUSCATE_FLAG", String.valueOf(deobfuscateStack));
|
||||||
return script;
|
return script;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("IO error occurred writing debug information", e);
|
throw new RuntimeException("IO error occurred writing debug information", e);
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class DevServer {
|
||||||
private String fileName = "classes.js";
|
private String fileName = "classes.js";
|
||||||
private List<String> sourcePath = new ArrayList<>();
|
private List<String> sourcePath = new ArrayList<>();
|
||||||
private boolean indicator;
|
private boolean indicator;
|
||||||
|
private boolean deobfuscateStack;
|
||||||
private boolean reloadedAutomatically;
|
private boolean reloadedAutomatically;
|
||||||
private TeaVMToolLog log;
|
private TeaVMToolLog log;
|
||||||
private CodeServlet servlet;
|
private CodeServlet servlet;
|
||||||
|
@ -79,6 +80,10 @@ public class DevServer {
|
||||||
this.indicator = indicator;
|
this.indicator = indicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDeobfuscateStack(boolean deobfuscateStack) {
|
||||||
|
this.deobfuscateStack = deobfuscateStack;
|
||||||
|
}
|
||||||
|
|
||||||
public void setReloadedAutomatically(boolean reloadedAutomatically) {
|
public void setReloadedAutomatically(boolean reloadedAutomatically) {
|
||||||
this.reloadedAutomatically = reloadedAutomatically;
|
this.reloadedAutomatically = reloadedAutomatically;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +131,7 @@ public class DevServer {
|
||||||
servlet.setLog(log);
|
servlet.setLog(log);
|
||||||
servlet.getSourcePath().addAll(sourcePath);
|
servlet.getSourcePath().addAll(sourcePath);
|
||||||
servlet.setIndicator(indicator);
|
servlet.setIndicator(indicator);
|
||||||
|
servlet.setDeobfuscateStack(deobfuscateStack);
|
||||||
servlet.setAutomaticallyReloaded(reloadedAutomatically);
|
servlet.setAutomaticallyReloaded(reloadedAutomatically);
|
||||||
servlet.setPort(port);
|
servlet.setPort(port);
|
||||||
servlet.setDebugPort(debugPort);
|
servlet.setDebugPort(debugPort);
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.devserver.deobfuscate;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSFunctor;
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
|
||||||
|
@JSFunctor
|
||||||
|
public interface DeobfuscateFunction extends JSObject {
|
||||||
|
Frame[] apply(String stack);
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.devserver.deobfuscate;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.teavm.debugging.information.DebugInformation;
|
||||||
|
import org.teavm.debugging.information.SourceLocation;
|
||||||
|
import org.teavm.jso.JSBody;
|
||||||
|
import org.teavm.jso.ajax.XMLHttpRequest;
|
||||||
|
import org.teavm.jso.core.JSArray;
|
||||||
|
import org.teavm.jso.core.JSRegExp;
|
||||||
|
import org.teavm.jso.core.JSString;
|
||||||
|
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||||
|
import org.teavm.jso.typedarrays.Int8Array;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public final class Deobfuscator {
|
||||||
|
private static final JSRegExp FRAME_PATTERN = JSRegExp.create("^ +at ([^(]+) *\\((.+):([0-9]+):([0-9]+)\\) *$");
|
||||||
|
|
||||||
|
private Deobfuscator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
loadDeobfuscator(args[0], args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadDeobfuscator(String fileName, String classesFileName) {
|
||||||
|
XMLHttpRequest xhr = XMLHttpRequest.create();
|
||||||
|
xhr.setResponseType("arraybuffer");
|
||||||
|
xhr.onComplete(() -> {
|
||||||
|
installDeobfuscator(xhr.getResponse().cast(), classesFileName);
|
||||||
|
});
|
||||||
|
xhr.open("GET", fileName);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void installDeobfuscator(ArrayBuffer buffer, String classesFileName) {
|
||||||
|
Int8Array array = Int8Array.create(buffer);
|
||||||
|
DebugInformation debugInformation;
|
||||||
|
try {
|
||||||
|
debugInformation = DebugInformation.read(new Int8ArrayInputStream(array));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeobfuscateFunction(stack -> {
|
||||||
|
List<Frame> frames = new ArrayList<>();
|
||||||
|
for (String line : splitLines(stack)) {
|
||||||
|
JSArray<JSString> groups = FRAME_PATTERN.exec(JSString.valueOf(line));
|
||||||
|
if (groups == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String functionName = groups.get(1).stringValue();
|
||||||
|
String fileName = groups.get(2).stringValue();
|
||||||
|
int lineNumber = Integer.parseInt(groups.get(3).stringValue());
|
||||||
|
int columnNumber = Integer.parseInt(groups.get(4).stringValue());
|
||||||
|
Frame frame = deobfuscateFrame(debugInformation, classesFileName, fileName, lineNumber, columnNumber);
|
||||||
|
if (frame == null) {
|
||||||
|
frame = createDefaultFrame(fileName, functionName, lineNumber);
|
||||||
|
}
|
||||||
|
frames.add(frame);
|
||||||
|
}
|
||||||
|
return frames.toArray(new Frame[0]);
|
||||||
|
});
|
||||||
|
DeobfuscatorCallback callback = getCallback();
|
||||||
|
if (callback != null) {
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Frame deobfuscateFrame(DebugInformation debugInformation, String classesFileName,
|
||||||
|
String fileName, int lineNumber, int columnNumber) {
|
||||||
|
if (!fileName.equals(classesFileName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodReference method = debugInformation.getMethodAt(lineNumber - 1, columnNumber - 1);
|
||||||
|
if (method == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceLocation location = debugInformation.getSourceLocation(lineNumber - 1, columnNumber - 1);
|
||||||
|
|
||||||
|
String decodedFileName = location != null ? location.getFileName() : null;
|
||||||
|
if (decodedFileName != null) {
|
||||||
|
decodedFileName = decodedFileName.substring(decodedFileName.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame frame = createEmptyFrame();
|
||||||
|
frame.setClassName(method.getClassName());
|
||||||
|
frame.setMethodName(method.getName());
|
||||||
|
frame.setFileName(decodedFileName);
|
||||||
|
if (location != null) {
|
||||||
|
frame.setLineNumber(location.getLine());
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Frame createDefaultFrame(String fileName, String functionName, int lineNumber) {
|
||||||
|
Frame frame = createEmptyFrame();
|
||||||
|
frame.setFileName(fileName);
|
||||||
|
frame.setMethodName(functionName != null ? functionName : "<unknown function>");
|
||||||
|
frame.setClassName("<JS>");
|
||||||
|
frame.setLineNumber(lineNumber);
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] splitLines(String text) {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
int index = 0;
|
||||||
|
while (index < text.length()) {
|
||||||
|
int next = text.indexOf('\n', index);
|
||||||
|
if (next < 0) {
|
||||||
|
next = text.length();
|
||||||
|
}
|
||||||
|
result.add(text.substring(index, next));
|
||||||
|
index = next + 1;
|
||||||
|
}
|
||||||
|
return result.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSBody(script = "return {};")
|
||||||
|
private static native Frame createEmptyFrame();
|
||||||
|
|
||||||
|
@JSBody(params = "f", script = "window.$rt_decodeStack = f;")
|
||||||
|
private static native void setDeobfuscateFunction(DeobfuscateFunction f);
|
||||||
|
|
||||||
|
@JSBody(script = "return typeof $teavm_deobfuscator_callback === 'function'"
|
||||||
|
+ "? $teavm_deobfuscator_callback : null;")
|
||||||
|
private static native DeobfuscatorCallback getCallback();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.devserver.deobfuscate;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSFunctor;
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
|
||||||
|
@JSFunctor
|
||||||
|
public interface DeobfuscatorCallback extends JSObject {
|
||||||
|
void run();
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.devserver.deobfuscate;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
|
public interface Frame extends JSObject {
|
||||||
|
@JSProperty
|
||||||
|
void setClassName(String className);
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
void setFileName(String fileName);
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
void setMethodName(String methodName);
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
void setLineNumber(int lineNumber);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.devserver.deobfuscate;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.teavm.jso.typedarrays.Int8Array;
|
||||||
|
|
||||||
|
public class Int8ArrayInputStream extends InputStream {
|
||||||
|
private Int8Array array;
|
||||||
|
private int pos;
|
||||||
|
|
||||||
|
public Int8ArrayInputStream(Int8Array array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() {
|
||||||
|
if (pos >= array.getLength()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return array.get(pos++) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) {
|
||||||
|
if (pos >= array.getLength()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int count = Math.min(len, array.getLength() - pos);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
b[off++] = array.get(pos++);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,11 +13,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
(function () {
|
(function (window) {
|
||||||
var boot = BOOT_FLAG;
|
var boot = BOOT_FLAG;
|
||||||
var reload = RELOAD_FLAG;
|
var reload = RELOAD_FLAG;
|
||||||
var indicatorVisible = INDICATOR_FLAG;
|
var indicatorVisible = INDICATOR_FLAG;
|
||||||
var debugPort = DEBUG_PORT;
|
var debugPort = DEBUG_PORT;
|
||||||
|
var deobfuscate = DEOBFUSCATE_FLAG;
|
||||||
|
var fileName = FILE_NAME;
|
||||||
|
var pathToFile = PATH_TO_FILE;
|
||||||
|
|
||||||
function createWebSocket() {
|
function createWebSocket() {
|
||||||
return new WebSocket("ws://WS_PATH");
|
return new WebSocket("ws://WS_PATH");
|
||||||
|
@ -128,10 +131,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function installDeobfuscator() {
|
||||||
|
if (!deobfuscate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof main === 'function') {
|
||||||
|
var oldMain = main;
|
||||||
|
main = function() {
|
||||||
|
var args = arguments;
|
||||||
|
window.$teavm_deobfuscator_callback = function() {
|
||||||
|
oldMain.apply(window, args);
|
||||||
|
};
|
||||||
|
var elem = document.createElement("script");
|
||||||
|
elem.src = pathToFile + fileName + ".deobfuscator.js";
|
||||||
|
elem.onload = function() {
|
||||||
|
$teavm_deobfuscator([pathToFile + fileName + ".teavmdbg", pathToFile + fileName]);
|
||||||
|
};
|
||||||
|
document.head.append(elem);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boot) {
|
||||||
|
installDeobfuscator();
|
||||||
|
}
|
||||||
|
|
||||||
function startMain() {
|
function startMain() {
|
||||||
ws.close();
|
ws.close();
|
||||||
window.removeEventListener("load", onLoad);
|
window.removeEventListener("load", onLoad);
|
||||||
document.body.removeChild(indicator.container);
|
document.body.removeChild(indicator.container);
|
||||||
|
installDeobfuscator();
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +180,7 @@
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
} else if (boot) {
|
} else if (boot) {
|
||||||
var scriptElem = document.createElement("script");
|
var scriptElem = document.createElement("script");
|
||||||
scriptElem.src = "FILE_NAME";
|
scriptElem.src = pathToFile + fileName;
|
||||||
scriptElem.onload = startMain;
|
scriptElem.onload = startMain;
|
||||||
document.head.appendChild(scriptElem);
|
document.head.appendChild(scriptElem);
|
||||||
}
|
}
|
||||||
|
@ -181,4 +211,4 @@
|
||||||
window.addEventListener("message", connectDebugAgent);
|
window.addEventListener("message", connectDebugAgent);
|
||||||
window.postMessage({teavmDebugger: {port: debugPort}}, "*");
|
window.postMessage({teavmDebugger: {port: debugPort}}, "*");
|
||||||
}
|
}
|
||||||
})();
|
})(this);
|
|
@ -22,6 +22,7 @@ public class DevServerConfiguration {
|
||||||
public String[] classPath;
|
public String[] classPath;
|
||||||
public String[] sourcePath;
|
public String[] sourcePath;
|
||||||
public boolean indicator;
|
public boolean indicator;
|
||||||
|
public boolean deobfuscateStack;
|
||||||
public boolean autoReload;
|
public boolean autoReload;
|
||||||
public int port;
|
public int port;
|
||||||
public String pathToFile;
|
public String pathToFile;
|
||||||
|
|
|
@ -122,6 +122,9 @@ public class DevServerRunner extends UnicastRemoteObject implements DevServerMan
|
||||||
case "-i":
|
case "-i":
|
||||||
server.setIndicator(true);
|
server.setIndicator(true);
|
||||||
break;
|
break;
|
||||||
|
case "-deobf":
|
||||||
|
server.setDeobfuscateStack(true);
|
||||||
|
break;
|
||||||
case "-a":
|
case "-a":
|
||||||
server.setReloadedAutomatically(true);
|
server.setReloadedAutomatically(true);
|
||||||
break;
|
break;
|
||||||
|
@ -178,6 +181,9 @@ public class DevServerRunner extends UnicastRemoteObject implements DevServerMan
|
||||||
if (options.indicator) {
|
if (options.indicator) {
|
||||||
arguments.add("-i");
|
arguments.add("-i");
|
||||||
}
|
}
|
||||||
|
if (options.deobfuscateStack) {
|
||||||
|
arguments.add("-deobf");
|
||||||
|
}
|
||||||
if (options.autoReload) {
|
if (options.autoReload) {
|
||||||
arguments.add("-a");
|
arguments.add("-a");
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class TeaVMDevServerConfiguration extends ModuleBasedConfiguration<RunCon
|
||||||
private String pathToFile = "";
|
private String pathToFile = "";
|
||||||
private String fileName = "classes.js";
|
private String fileName = "classes.js";
|
||||||
private boolean indicator = true;
|
private boolean indicator = true;
|
||||||
|
private boolean deobfuscateStack = true;
|
||||||
private boolean automaticallyReloaded;
|
private boolean automaticallyReloaded;
|
||||||
private int maxHeap = 1024;
|
private int maxHeap = 1024;
|
||||||
private String proxyUrl = "";
|
private String proxyUrl = "";
|
||||||
|
@ -155,6 +156,16 @@ public class TeaVMDevServerConfiguration extends ModuleBasedConfiguration<RunCon
|
||||||
this.indicator = indicator;
|
this.indicator = indicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
@Tag
|
||||||
|
public boolean isDeobfuscateStack() {
|
||||||
|
return deobfuscateStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeobfuscateStack(boolean deobfuscateStack) {
|
||||||
|
this.deobfuscateStack = deobfuscateStack;
|
||||||
|
}
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
@Tag
|
@Tag
|
||||||
public boolean isAutomaticallyReloaded() {
|
public boolean isAutomaticallyReloaded() {
|
||||||
|
|
|
@ -78,6 +78,7 @@ public class TeaVMDevServerRunState implements RunProfileState {
|
||||||
config.fileName = configuration.getFileName();
|
config.fileName = configuration.getFileName();
|
||||||
config.port = configuration.getPort();
|
config.port = configuration.getPort();
|
||||||
config.indicator = configuration.isIndicator();
|
config.indicator = configuration.isIndicator();
|
||||||
|
config.deobfuscateStack = configuration.isDeobfuscateStack();
|
||||||
config.autoReload = configuration.isAutomaticallyReloaded();
|
config.autoReload = configuration.isAutomaticallyReloaded();
|
||||||
config.mainClass = configuration.getMainClass();
|
config.mainClass = configuration.getMainClass();
|
||||||
config.maxHeap = configuration.getMaxHeap();
|
config.maxHeap = configuration.getMaxHeap();
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
|
||||||
private JTextField pathToFileField;
|
private JTextField pathToFileField;
|
||||||
private JTextField fileNameField;
|
private JTextField fileNameField;
|
||||||
private JCheckBox indicatorField;
|
private JCheckBox indicatorField;
|
||||||
|
private JCheckBox deobfuscateStackField;
|
||||||
private JCheckBox autoReloadField;
|
private JCheckBox autoReloadField;
|
||||||
private JFormattedTextField maxHeapField;
|
private JFormattedTextField maxHeapField;
|
||||||
private JTextField proxyUrlField;
|
private JTextField proxyUrlField;
|
||||||
|
@ -76,6 +77,7 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
|
||||||
fileNameField = new JTextField();
|
fileNameField = new JTextField();
|
||||||
pathToFileField = new JTextField();
|
pathToFileField = new JTextField();
|
||||||
indicatorField = new JCheckBox("Display indicator on a web page:");
|
indicatorField = new JCheckBox("Display indicator on a web page:");
|
||||||
|
deobfuscateStackField = new JCheckBox("Deobfuscate stack traces in exceptions");
|
||||||
autoReloadField = new JCheckBox("Reload page automatically:");
|
autoReloadField = new JCheckBox("Reload page automatically:");
|
||||||
maxHeapField = new JFormattedTextField(new DecimalFormat("#0"));
|
maxHeapField = new JFormattedTextField(new DecimalFormat("#0"));
|
||||||
|
|
||||||
|
@ -118,6 +120,7 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
|
||||||
add(pathToFileField, constraints);
|
add(pathToFileField, constraints);
|
||||||
|
|
||||||
add(indicatorField, constraints);
|
add(indicatorField, constraints);
|
||||||
|
add(deobfuscateStackField, constraints);
|
||||||
add(autoReloadField, constraints);
|
add(autoReloadField, constraints);
|
||||||
|
|
||||||
add(new JLabel("Server heap limit:"), labelConstraints);
|
add(new JLabel("Server heap limit:"), labelConstraints);
|
||||||
|
@ -137,6 +140,7 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
|
||||||
fileNameField.setText(configuration.getFileName());
|
fileNameField.setText(configuration.getFileName());
|
||||||
pathToFileField.setText(configuration.getPathToFile());
|
pathToFileField.setText(configuration.getPathToFile());
|
||||||
indicatorField.setSelected(configuration.isIndicator());
|
indicatorField.setSelected(configuration.isIndicator());
|
||||||
|
deobfuscateStackField.setSelected(configuration.isDeobfuscateStack());
|
||||||
autoReloadField.setSelected(configuration.isAutomaticallyReloaded());
|
autoReloadField.setSelected(configuration.isAutomaticallyReloaded());
|
||||||
maxHeapField.setText(Integer.toString(configuration.getMaxHeap()));
|
maxHeapField.setText(Integer.toString(configuration.getMaxHeap()));
|
||||||
portField.setText(Integer.toString(configuration.getPort()));
|
portField.setText(Integer.toString(configuration.getPort()));
|
||||||
|
@ -151,6 +155,7 @@ public class TeaVMDevServerSettingsPanel extends JPanel {
|
||||||
configuration.setFileName(fileNameField.getText().trim());
|
configuration.setFileName(fileNameField.getText().trim());
|
||||||
configuration.setPathToFile(pathToFileField.getText().trim());
|
configuration.setPathToFile(pathToFileField.getText().trim());
|
||||||
configuration.setIndicator(indicatorField.isSelected());
|
configuration.setIndicator(indicatorField.isSelected());
|
||||||
|
configuration.setDeobfuscateStack(deobfuscateStackField.isSelected());
|
||||||
configuration.setAutomaticallyReloaded(autoReloadField.isSelected());
|
configuration.setAutomaticallyReloaded(autoReloadField.isSelected());
|
||||||
if (!maxHeapField.getText().trim().isEmpty()) {
|
if (!maxHeapField.getText().trim().isEmpty()) {
|
||||||
configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText()));
|
configuration.setMaxHeap(Integer.parseInt(maxHeapField.getText()));
|
||||||
|
|
|
@ -110,6 +110,9 @@ public class TeaVMCompileMojo extends AbstractMojo {
|
||||||
@Parameter(property = "teavm.mainClass")
|
@Parameter(property = "teavm.mainClass")
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
|
|
||||||
|
@Parameter(property = "teavm.entryPointName", defaultValue = "main")
|
||||||
|
private String entryPointName;
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private String[] classesToPreserve;
|
private String[] classesToPreserve;
|
||||||
|
|
||||||
|
@ -258,6 +261,7 @@ public class TeaVMCompileMojo extends AbstractMojo {
|
||||||
builder.setLog(toolLog);
|
builder.setLog(toolLog);
|
||||||
try {
|
try {
|
||||||
builder.setMainClass(mainClass);
|
builder.setMainClass(mainClass);
|
||||||
|
builder.setEntryPointName(entryPointName);
|
||||||
if (!targetFileName.isEmpty()) {
|
if (!targetFileName.isEmpty()) {
|
||||||
builder.setTargetFileName(targetFileName);
|
builder.setTargetFileName(targetFileName);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user