[FEATURE] Improve LaunchServer start

This commit is contained in:
Gravita 2023-12-20 04:45:41 +07:00
parent 31489a2b24
commit f8b060422e
7 changed files with 67 additions and 153 deletions

View file

@ -1,4 +1,4 @@
def mainClassName = "pro.gravit.launchserver.LaunchServerStarter"
def mainClassName = "pro.gravit.launchserver.Main"
def mainAgentName = "pro.gravit.launchserver.StarterAgent"
evaluationDependsOn(':Launcher')
@ -65,9 +65,7 @@
archiveClassifier.set('clean')
manifest.attributes("Main-Class": mainClassName,
"Premain-Class": mainAgentName,
"Can-Redefine-Classes": "true",
"Can-Retransform-Classes": "true",
"Can-Set-Native-Method-Prefix": "true"
"Automatic-Module-Name": "launchserver"
)
from sourceSets.main.output
}
@ -84,13 +82,15 @@ pack project(':LauncherModernCore')
bundle group: 'org.jline', name: 'jline-terminal', version: rootProject['verJline']
bundle group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: rootProject['verBcpkix']
bundle group: 'org.ow2.asm', name: 'asm-commons', version: rootProject['verAsm']
bundle group: 'io.netty', name: 'netty-all', version: rootProject['verNetty']
bundle group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
bundle group: 'io.netty', name: 'netty-transport-classes-epoll', version: rootProject['verNetty']
bundle group: 'io.netty', name: 'netty-transport-native-epoll', version: rootProject['verNetty'], classifier: 'linux-x86_64'
bundle group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j']
bundle group: 'com.mysql', name: 'mysql-connector-j', version: rootProject['verMySQLConn']
bundle group: 'org.postgresql', name: 'postgresql', version: rootProject['verPostgreSQLConn']
bundle group: 'com.guardsquare', name: 'proguard-base', version: rootProject['verProguard']
bundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: rootProject['verLog4j']
bundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: rootProject['verLog4j']
bundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j2-impl', version: rootProject['verLog4j']
bundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: rootProject['verJwt']
bundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: rootProject['verJwt']
bundle group: 'io.jsonwebtoken', name: 'jjwt-gson', version: rootProject['verJwt']
@ -104,16 +104,6 @@ pack project(':LauncherModernCore')
exclude group: 'org.slf4j'
}
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j']) {
exclude group: 'org.apache.ant'
exclude group: 'net.java.abeille'
exclude group: 'foxtrot'
exclude group: 'com.jgoodies'
exclude group: 'org.slf4j'
}
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-win32') { transitive = false }
launch4j('net.sf.launch4j:launch4j:' + rootProject['verLaunch4j'] + ':workdir-linux64') { transitive = false }
compileOnlyA group: 'com.google.guava', name: 'guava', version: rootProject['verGuavaC']
// Do not update (laggy deps).
compileOnlyA 'log4j:log4j:1.2.17'

View file

@ -28,12 +28,15 @@
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.launch.LaunchOptions;
import pro.gravit.utils.launch.ModuleLaunch;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.Security;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
public class LaunchServerStarter {
@ -42,15 +45,10 @@ public class LaunchServerStarter {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) throws Exception {
JVMHelper.checkStackTrace(LaunchServerStarter.class);
JVMHelper.verifySystemProperties(LaunchServer.class, true);
JVMHelper.verifySystemProperties(LaunchServer.class, false);
//LogHelper.addOutput(IOHelper.WORKING_DIR.resolve("LaunchServer.log"));
LogHelper.printVersion("LaunchServer");
LogHelper.printLicense("LaunchServer");
if (!StarterAgent.isAgentStarted()) {
LogHelper.error("StarterAgent is not started!");
LogHelper.error("You should add to JVM options this option: `-javaagent:LaunchServer.jar`");
}
Path dir = IOHelper.WORKING_DIR;
Path configFile, runtimeConfigFile;
try {

View file

@ -0,0 +1,53 @@
package pro.gravit.launchserver;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.launch.ClassLoaderControl;
import pro.gravit.utils.launch.LaunchOptions;
import pro.gravit.utils.launch.ModuleLaunch;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Main {
private static final List<String> classpathOnly = List.of("proguard", "jline", "kotlin", "epoll");
private static boolean isClasspathOnly(Path path) {
var fileName = path.getFileName().toString();
for(var e : classpathOnly) {
if(fileName.contains(e)) {
return true;
}
}
return false;
}
public static void main(String[] args) throws Throwable {
ModuleLaunch launch = new ModuleLaunch();
LaunchOptions options = new LaunchOptions();
options.disablePackageDelegateSupport = true;
options.moduleConf = new LaunchOptions.ModuleConf();
List<Path> libraries;
try(Stream<Path> files = Files.walk(Path.of("libraries"), FileVisitOption.FOLLOW_LINKS)) {
libraries = new ArrayList<>(files.filter(e -> e.getFileName().toString().endsWith(".jar")).toList());
}
List<Path> classpath = new ArrayList<>();
List<String> modulepath = new ArrayList<>();
for(var l : libraries) {
if(isClasspathOnly(l)) {
classpath.add(l);
} else {
modulepath.add(l.toAbsolutePath().toString());
}
}
classpath.add(IOHelper.getCodeSource(LaunchServerStarter.class));
options.moduleConf.modulePath.addAll(modulepath);
options.moduleConf.modules.add("ALL-MODULE-PATH");
ClassLoaderControl control = launch.init(classpath, "natives", options);
ModuleLayer.Controller controller = (ModuleLayer.Controller) control.getJava9ModuleController();
launch.launch("pro.gravit.launchserver.LaunchServerStarter", null, Arrays.asList(args));
}
}

View file

@ -20,47 +20,6 @@ public static boolean isAgentStarted() {
}
public static void premain(String agentArgument, Instrumentation inst) {
StarterAgent.inst = inst;
libraries = Paths.get(Optional.ofNullable(agentArgument).map(String::trim).filter(e -> !e.isEmpty()).orElse("libraries"));
isStarted = true;
try {
Files.walkFileTree(libraries, Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor());
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
private static final class StarterVisitor extends SimpleFileVisitor<Path> {
private static final Set<PosixFilePermission> DPERMS;
static {
Set<PosixFilePermission> perms = new HashSet<>(Arrays.asList(PosixFilePermission.values()));
perms.remove(PosixFilePermission.OTHERS_WRITE);
perms.remove(PosixFilePermission.GROUP_WRITE);
DPERMS = Collections.unmodifiableSet(perms);
}
private final boolean fixLib;
private StarterVisitor() {
Path filef = StarterAgent.libraries.resolve(".libraries_chmoded");
this.fixLib = !Files.exists(filef) && !Boolean.getBoolean("launcher.noLibrariesPosixPermsFix");
if (fixLib) {
try {
Files.deleteIfExists(filef);
Files.createFile(filef);
} catch (Throwable ignored) {
}
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (fixLib && Files.getFileAttributeView(file, PosixFileAttributeView.class) != null)
Files.setPosixFilePermissions(file, DPERMS);
if (file.toFile().getName().endsWith(".jar"))
inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile()));
return super.visitFile(file, attrs);
}
throw new UnsupportedOperationException("Please remove -javaagent option from start.sh");
}
}

View file

@ -1,8 +1,5 @@
package pro.gravit.launchserver.binary.tasks.exe;
import net.sf.launch4j.Builder;
import net.sf.launch4j.Log;
import net.sf.launch4j.config.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launchserver.LaunchServer;
@ -37,89 +34,6 @@ public String getName() {
@Override
public Path process(Path inputFile) throws IOException {
logger.info("Building launcher EXE binary file (Using Launch4J)");
Path output = setConfig();
// Set favicon path
Config config = ConfigPersister.getInstance().getConfig();
if (IOHelper.isFile(faviconFile))
config.setIcon(faviconFile.toFile());
else {
config.setIcon(null);
logger.warn("Missing favicon.ico file");
}
// Start building
Builder builder = new Builder(Launch4JLog.INSTANCE);
try {
builder.build();
} catch (Throwable e) {
throw new IOException(e);
}
return output;
}
private Path setConfig() {
Path path = server.launcherEXEBinary.nextPath(getName());
Config config = new Config();
// Set file options
config.setChdir(".");
config.setErrTitle("JVM Error");
config.setDownloadUrl(server.config.launch4j.downloadUrl);
if (server.config.launch4j.supportURL != null) config.setSupportUrl(server.config.launch4j.supportURL);
// Set boolean options
config.setPriorityIndex(0);
config.setHeaderType(Config.GUI_HEADER);
config.setStayAlive(false);
config.setRestartOnCrash(false);
// Prepare JRE
Jre jre = new Jre();
jre.setMinVersion(server.config.launch4j.minVersion);
if (server.config.launch4j.setMaxVersion)
jre.setMaxVersion(server.config.launch4j.maxVersion);
jre.setPath(System.getProperty("java.home"));
config.setJre(jre);
// Prepare version info (product)
VersionInfo info = new VersionInfo();
info.setProductName(server.config.launch4j.productName);
info.setProductVersion(formatVars(server.config.launch4j.productVer));
info.setFileDescription(server.config.launch4j.fileDesc);
info.setFileVersion(formatVars(server.config.launch4j.fileVer));
info.setCopyright(server.config.launch4j.copyright);
info.setTrademarks(server.config.launch4j.trademarks);
info.setInternalName(formatVars(server.config.launch4j.internalName));
// Prepare version info (file)
info.setTxtFileVersion(formatVars(server.config.launch4j.txtFileVersion));
info.setTxtProductVersion(formatVars(server.config.launch4j.txtProductVersion));
// Prepare version info (misc)
info.setOriginalFilename(path.getFileName().toString());
info.setLanguage(LanguageID.RUSSIAN);
config.setVersionInfo(info);
// Set JAR wrapping options
config.setDontWrapJar(false);
config.setJar(server.launcherBinary.syncBinaryFile.toFile());
config.setOutfile(path.toFile());
// Return prepared config
ConfigPersister.getInstance().setAntConfig(config, null);
return path;
}
private final static class Launch4JLog extends Log {
private static final Launch4JLog INSTANCE = new Launch4JLog();
private static final Logger logger = LogManager.getLogger();
@Override
public void append(String s) {
logger.info(s);
}
@Override
public void clear() {
// Do nothing
}
throw new UnsupportedOperationException("Launch4j not supported");
}
}

View file

@ -33,7 +33,7 @@ public class SimpleModuleManager implements LauncherModulesManager {
protected final ModulesConfigManager modulesConfigManager;
protected final Path modulesDir;
protected final LauncherTrustManager trustManager;
protected final PublicURLClassLoader classLoader = new PublicURLClassLoader(new URL[]{});
protected final PublicURLClassLoader classLoader = new PublicURLClassLoader(new URL[]{}, SimpleModuleManager.class.getClassLoader());
protected LauncherInitContext initContext;
public SimpleModuleManager(Path modulesDir, Path configDir) {

View file

@ -10,7 +10,7 @@
verBcprov = '1.70'
verGson = '2.10.1'
verBcpkix = '1.70'
verSlf4j = '1.7.36'
verSlf4j = '2.0.9'
verLog4j = '2.20.0'
verMySQLConn = '8.1.0'
verPostgreSQLConn = '42.6.0'