大家好,欢迎来到IT知识分享网。
背景
一个应用了多年的自己编写的java的启动方式,觉得甚是方便,大致与SpringBoot启动jar的方式类似,于是就想把它共享出来,共勉之。
启动时序:
核心类图:
代码共享
java核心源码:
package com.what21;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class BootstrapClassLoader extends URLClassLoader {
static final String JAR = ".jar";
static final String ZIP = ".zip";
public BootstrapClassLoader(URL[] urls) {
super(urls);
}
public static class Build {
/**
* @param parentPath
* @return
*/
public static BootstrapClassLoader build(String parentPath) {
URL[] urls = toURL(parentPath);
// System.out.println(Arrays.toString(urls));
return new BootstrapClassLoader(urls);
}
/**
* @param parentPath
* @return
*/
public static URL[] toURL(String parentPath) {
if (parentPath == null) {
return null;
}
File file = new File(parentPath);
if (!file.exists()) {
return null;
}
List<String> pathList = new ArrayList<String>();
listFile(parentPath, pathList);
URL[] urlArray = new URL[pathList.size()];
for (int i = 0; i < pathList.size(); i++) {
try {
urlArray[i] = new URL("file:///" + pathList.get(i));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return urlArray;
}
/**
* @param filePath
* @param pathList
*/
static void listFile(String filePath, List<String> pathList) {
File file = new File(filePath);
File[] files = file.listFiles();
for (File subFile : files) {
recursionFile(subFile.getAbsolutePath(), pathList);
}
}
/**
* @param filePath
* @param pathList
*/
static void recursionFile(String filePath, List<String> pathList) {
File file = new File(filePath);
if (file.isDirectory()) {
for (File subFile : file.listFiles()) {
listFile(subFile.getAbsolutePath(), pathList);
}
} else {
String absolutePath = file.getAbsolutePath().toLowerCase();
if (absolutePath.endsWith(".jar") || absolutePath.endsWith(".zip")) {
pathList.add(file.getAbsolutePath());
}
}
}
}
}
package com.what21;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
public final class Bootstrap {
private static final String BIN = "bin";
private static final String LIB = "lib";
private static final String APPS = "apps";
private static final String launchClass = "com.what21.apps.ApplicationBootstrap";
private static final String launchMethod = "launch";
private static BootstrapClassLoader bootstrapClassLoader;
/**
* @return
*/
private static String applicationHome() {
// 获取当前系统编码
String encoding = System.getProperty("sun.jnu.encoding");
if (encoding == null || "".equals(encoding)) {
encoding = "UTF-8";
}
// 获取URL,进行解码
String runPath = Bootstrap.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodeRunPath = null;
try {
decodeRunPath = URLDecoder.decode(runPath, encoding);
} catch (Exception e) {
}
File runFile = new File(decodeRunPath);
if (!runFile.exists()) {
try {
decodeRunPath = URLDecoder.decode(runPath, "UTF-8");
} catch (Exception e) {
}
runFile = new File(decodeRunPath);
}
File runHomeFile = runFile.getParentFile();
String homePath = "";
if (BIN.equalsIgnoreCase(runHomeFile.getName())) {
homePath = runHomeFile.getParent();
} else {
homePath = runHomeFile.getAbsolutePath();
}
return homePath;
}
/**
* @param obj
*/
private static void logger(Object obj) {
System.out.println(obj);
}
/**
* @param pidPath
* @param pid
*/
private static void writeProcessPid(String pidPath, String pid) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(pidPath));
fos.write(pid.getBytes());
fos.flush();
} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
fos = null;
}
}
}
/**
* @param applicationApps
* @return
*/
private static String[] toApplicationArray(String applicationApps) {
List<String> appList = new ArrayList<String>();
File appsFile = new File(applicationApps);
if (appsFile != null) {
File[] appFileArray = appsFile.listFiles();
for (File appFile : appFileArray) {
if (appFile.isDirectory()) {
appList.add(appFile.getAbsolutePath());
}
}
}
return appList.toArray(new String[] {});
}
/**
* @param args
*/
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
// logger("// sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding"));
logger("// file.encoding: " + System.getProperty("file.encoding"));
// home
String applicationHome = applicationHome();
System.setProperty("application.home", applicationHome);
logger("// application.home: " + applicationHome);
// lib
String applicationLib = applicationHome + "/" + LIB + "/";
System.setProperty("application.lib", applicationLib);
logger("// application.lib: " + applicationLib);
// apps
String applicationApps = applicationHome + "/" + APPS + "/";
System.setProperty("application.apps", applicationApps);
logger("// application.apps: " + applicationApps);
bootstrapClassLoader = BootstrapClassLoader.Build.build(applicationLib);
logger("// application.classloader: " + bootstrapClassLoader);
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
String[] applicationPathArray = toApplicationArray(applicationApps);
// invoke
try {
Class<? extends Object> clazz = bootstrapClassLoader.loadClass(launchClass);
Object object = clazz.newInstance();
Method method = clazz.getDeclaredMethod(launchMethod, new Class[] { String[].class });
method.setAccessible(true);
method.invoke(object, new Object[] { applicationPathArray });
} catch (Exception e) {
e.printStackTrace();
}
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
String runName = ManagementFactory.getRuntimeMXBean().getName();
logger("// application.name: " + runName);
if (runName != null) {
String pid = runName.split("@")[0];
writeProcessPid(applicationHome + "/" + BIN + "/process.pid", pid);
}
long endTime = System.currentTimeMillis();
logger("// Application startup in " + (endTime - startTime) + " ms");
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
logger("/////////////////////////////////////////////////////////////////////////////////////////////");
}
}
Linux启动脚本:
#!/bin/bash
#==========================================================================================
# export JAVA_HOME=/opt/java/jdk1.8.0_221
export PATH=$JAVA_HOME/bin:$PATH
export JAVA_OPTS="-Xmx1024M -Xms512M -XX:MaxPermSize=256m"
export JAVA_JAR="startup-single-2.0.jar"
export JAVA_MAIN="com.what21.startup.SingleStartUp"
export LAUNCH_CLASS="com.what21.simba.netserv.launch.NetServDaemon.launch"
export LAUNCH_ARGS=""
export WORK_HOME=$(dirname "$PWD")
#==========================================================================================
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
#==========================================================================================
echo "Java Home <=====> $JAVA_HOME"
echo "JVM Parameters <=====> $JAVA_OPTS"
echo "Start Jar <=====> $JAVA_JAR"
echo "Start Class <=====> $JAVA_MAIN"
echo "Launch Class <=====> $LAUNCH_CLASS"
echo "Start Parameters <=====> $LAUNCH_ARGS"
echo "Execute Command <=====> $CMD"
#==========================================================================================
nohup $JAVA_HOME/bin/java -DWorkHome=$WORK_HOME $JAVA_OPTS -classpath "$CLASSPATH:./$JAVA_JAR" "$JAVA_MAIN" "$LAUNCH_CLASS" "$LAUNCH_ARGS" "$CMD" >/dev/null 2>&1 &
#==========================================================================================
Windows启动脚本:
@echo off
rem ========================================================================
rem set JAVA_HOME=D:\MyApps\Java\jdk1.8.0_131
set JAVA_OPTS="-Xmx1024M -Xms512M -XX:MaxPermSize=256m"
set JAVA_JAR="startup-single-2.0.jar"
set JAVA_MAIN="com.what21.startup.SingleStartUp"
set LAUNCH_CLASS="com.what21.simba.netserv.launch.NetServDaemon.launch"
set LAUNCH_ARGS=
rem ========================================================================
set CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
set WORK_HOME=%cd%
rem ========================================================================
rem 接收传入参数
rem ========================================================================
if "%1"=="" goto doStart
if "%1"=="start" goto doStart
if "%1"=="stop" goto doShutdown
rem ========================================================================
:doStart
set CMD=start
goto doExe
rem ========================================================================
:doShutdown
set CMD=stop
goto doExe
rem ========================================================================
:doExe
echo "================================================================================================================"
echo "Execute Directory <=====> %WORK_HOME%"
echo "Java Home <=====> %JAVA_HOME%"
echo "JVM Parameters <=====> %JAVA_OPTS%"
echo "Start Jar <=====> %JAVA_JAR%"
echo "Start Class <=====> %JAVA_MAIN%"
echo "Launch Class <=====> %LAUNCH_CLASS%"
echo "Start Parameters <=====> %LAUNCH_ARGS%"
echo "Execute Command <=====> %CMD%"
echo "================================================================================================================"
echo.
%JAVA_HOME%\bin\java -DWorkHome=$WORK_HOME "%JAVA_OPTS%" -classpath "%CLASSPATH%;%JAVA_JAR%" "%JAVA_MAIN%" "%LAUNCH_CLASS%" "%LAUNCH_ARGS%" "%CMD%" &
pause
goto end
rem ========================================================================
:notParam
echo not params
rem ========================================================================
:end
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/66633.html