org.apache.activemq.artemis.utils.SpawnedVMSupport Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.activemq.artemis.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.jboss.logging.Logger;
public class SpawnedVMSupport {
static ConcurrentHashMap startedProcesses = null;
private static final Logger log = Logger.getLogger(SpawnedVMSupport.class);
public static Process spawnVM(final String className, final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(className, new String[0], true, args);
}
public static Process spawnVM(final String className,
final boolean logOutput,
final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(className, new String[0], logOutput, args);
}
public static Process spawnVM(final String classPath,
final String className,
final boolean logOutput,
final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(classPath, className, new String[0], logOutput, args);
}
public static Process spawnVM(final String className, final String[] vmargs, final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(className, vmargs, true, args);
}
public static Process spawnVM(final String className,
final String[] vmargs,
final boolean logOutput,
final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(className, "-Xms512m", "-Xmx512m", vmargs, logOutput, true, true, args);
}
public static Process spawnVM(final String classpath,
final String className,
final String[] vmargs,
final boolean logOutput,
final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(classpath, className, "-Xms512m", "-Xmx512m", vmargs, logOutput, true, true, args);
}
public static Process spawnVMWithLogMacher(String wordMatch,
Runnable runnable,
final String className,
final String[] vmargs,
final boolean logOutput,
final String... args) throws Exception {
return SpawnedVMSupport.spawnVM(wordMatch, runnable, className, "-Xms512m", "-Xmx512m", vmargs, logOutput, true, true, args);
}
public static Process spawnVM(final String className,
final String memoryArg1,
final String memoryArg2,
final String[] vmargs,
final boolean logOutput,
final boolean logErrorOutput,
final boolean useLogging,
final String... args) throws Exception {
return spawnVM(null, null, className, memoryArg1, memoryArg2, vmargs, logOutput, logErrorOutput, useLogging, args);
}
public static Process spawnVM(final String classPath,
final String className,
final String memoryArg1,
final String memoryArg2,
final String[] vmargs,
final boolean logOutput,
final boolean logErrorOutput,
final boolean useLogging,
final String... args) throws Exception {
return spawnVM(classPath, null, null, className, memoryArg1, memoryArg2, vmargs, logOutput, logErrorOutput, useLogging, args);
}
public static Process spawnVM(final String wordMatch,
final Runnable wordRunning,
final String className,
final String memoryArg1,
final String memoryArg2,
final String[] vmargs,
final boolean logOutput,
final boolean logErrorOutput,
final boolean useLogging,
final String... args) throws Exception {
return spawnVM(getClassPath(), wordMatch, wordRunning, className, memoryArg1, memoryArg2, vmargs, logOutput, logErrorOutput, useLogging, args);
}
public static Process spawnVM(String classPath,
String wordMatch,
Runnable wordRunning,
String className,
String memoryArg1,
String memoryArg2,
String[] vmargs,
boolean logOutput,
boolean logErrorOutput,
boolean useLogging,
String... args) throws IOException, ClassNotFoundException {
return spawnVM(classPath, wordMatch, wordRunning, className, memoryArg1, memoryArg2, vmargs, logOutput, logErrorOutput, useLogging, -1, args);
}
public static String getClassPath() {
return System.getProperty("java.class.path");
}
public static String getClassPath(File libfolder) {
if (libfolder == null) {
return getClassPath();
}
StringBuilder stringBuilder = new StringBuilder();
boolean empty = true;
File[] files = libfolder.listFiles();
if (files == null) {
return getClassPath();
} else {
for (File f : files) {
if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip")) {
if (!empty) {
stringBuilder.append(File.pathSeparator);
}
empty = false;
stringBuilder.append(f.toString());
}
}
}
return stringBuilder.toString();
}
/**
* @param classPath
* @param wordMatch
* @param wordRunning
* @param className
* @param memoryArg1
* @param memoryArg2
* @param vmargs
* @param logOutput
* @param logErrorOutput
* @param useLogging
* @param debugPort if <=0 it means no debug
* @param args
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Process spawnVM(String classPath,
String wordMatch,
Runnable wordRunning,
String className,
String memoryArg1,
String memoryArg2,
String[] vmargs,
boolean logOutput,
boolean logErrorOutput,
boolean useLogging,
long debugPort,
String... args) throws IOException, ClassNotFoundException {
final String javaPath = Paths.get(System.getProperty("java.home"), "bin", "java").toAbsolutePath().toString();
ProcessBuilder builder = new ProcessBuilder();
if (memoryArg1 == null) {
memoryArg1 = "-Xms128m";
}
if (memoryArg2 == null) {
memoryArg2 = "-Xmx128m";
}
builder.command(javaPath, memoryArg1, memoryArg2);
if (debugPort > 0) {
builder.command().add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + debugPort);
}
builder.environment().put("CLASSPATH", classPath);
List commandList = builder.command();
if (vmargs != null) {
for (String arg : vmargs) {
commandList.add(arg);
}
}
// The logs will be huge if you don't set this
if (useLogging) {
commandList.add("-Djava.util.logging.manager=org.jboss.logmanager.LogManager");
commandList.add("-Dlogging.configuration=file:../config/logging.properties");
}
commandList.add("-Djava.io.tmpdir=" + System.getProperty("java.io.tmpdir", "./tmp"));
commandList.add("-Djava.library.path=" + System.getProperty("java.library.path", "./native/bin"));
String loggingConfigFile = System.getProperty("java.util.logging.config.file");
if (loggingConfigFile != null) {
commandList.add("-Djava.util.logging.config.file=" + loggingConfigFile + " ");
}
String jacocoAgent = System.getProperty("jacoco.agent");
if (jacocoAgent != null && !jacocoAgent.isEmpty()) {
commandList.add(jacocoAgent);
}
String loggingPlugin = System.getProperty("org.jboss.logging.Logger.pluginClass");
if (loggingPlugin != null) {
commandList.add("-Dorg.jboss.logging.Logger.pluginClass=" + loggingPlugin + " ");
}
commandList.add(className);
for (String arg : args) {
commandList.add(arg);
}
Process process = builder.start();
SpawnedVMSupport.startLogger(logOutput, wordMatch, wordRunning, className, process);
// Adding a reader to System.err, so the VM won't hang on a System.err.println as identified on this forum thread:
// http://www.jboss.org/index.html?module=bb&op=viewtopic&t=151815
ProcessLogger errorLogger = new ProcessLogger(logErrorOutput, process.getErrorStream(), className, wordMatch, wordRunning);
errorLogger.start();
if (startedProcesses != null) {
startedProcesses.put(process, className);
}
return process;
}
/**
* it will return a pair of dead / alive servers
*
* @return
*/
private static HashSet getAliveProcesses() {
HashSet aliveProcess = new HashSet<>();
if (startedProcesses != null) {
for (;;) {
try {
aliveProcess.clear();
for (Process process : startedProcesses.keySet()) {
if (process.isAlive()) {
aliveProcess.add(process);
process.destroyForcibly();
}
}
break;
} catch (Throwable e) {
e.printStackTrace();
}
}
}
return aliveProcess;
}
public static void forceKill() {
HashSet aliveProcess = getAliveProcesses();
for (Process alive : aliveProcess) {
for (int i = 0; i < 5; i++) {
alive.destroyForcibly();
try {
alive.waitFor(5, TimeUnit.SECONDS);
} catch (Exception e) {
}
}
}
}
public static void enableCheck() {
startedProcesses = new ConcurrentHashMap<>();
}
/**
* Check if all spawned processes are finished.
*/
public static boolean checkProcess() {
HashSet aliveProcess = getAliveProcesses();
try {
if (!aliveProcess.isEmpty()) {
StringBuffer buffer = new StringBuffer();
for (Process alive : aliveProcess) {
alive.destroyForcibly();
buffer.append(startedProcesses.get(alive) + " ");
}
return false;
}
} finally {
startedProcesses = null;
}
return true;
}
/**
* @param className
* @param process
* @throws ClassNotFoundException
*/
public static void startLogger(final boolean print,
final String wordMatch,
final Runnable wordRunanble,
final String className,
final Process process) throws ClassNotFoundException {
ProcessLogger outputLogger = new ProcessLogger(print, process.getInputStream(), className, wordMatch, wordRunanble);
outputLogger.start();
}
/**
* @param className
* @param process
* @throws ClassNotFoundException
*/
public static void startLogger(final String className, final Process process) throws ClassNotFoundException {
startLogger(true, null, null, className, process);
}
/**
* Redirect the input stream to a logger (as debug logs)
*/
static class ProcessLogger extends Thread {
private final InputStream is;
private final String className;
private final boolean print;
private final String wordMatch;
/**
* This will be executed when wordMatch is within any line on the log *
* *
*/
private final Runnable wordRunner;
ProcessLogger(final boolean print,
final InputStream is,
final String className,
String wordMatch,
Runnable wordRunner) throws ClassNotFoundException {
this.is = is;
this.print = print;
this.className = className;
this.wordMatch = wordMatch;
this.wordRunner = wordRunner;
setDaemon(true);
}
@Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (wordMatch != null && wordRunner != null) {
if (line.contains(wordMatch)) {
wordRunner.run();
}
}
if (print) {
System.out.println(className + ":" + line);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}