How to run a jar file from the teamcity custom plugin code - java

I am working on developing a plugin for teamcity . The requirement is to run a jar file from the code which does some custom operation. I tried with the below code, but its not working for me.Any ideas on how to run the jar, links to documentation or sample code will help me a lot to progress further
public class CustomBuildProcess extends BuildProcessAdapter
{
private static final String jarDir = "\\plugins\\teamcity-custom-plugin-agent\\lib\\metrics-17.6.4.4.jar";
#Override
public void start()
{
buildStatus = startProcess();
}
private BuildFinishedStatus startProcess() throws IOException
{
final GeneralCommandLine cmd = new GeneralCommandLine();
cmd.setExePath("java -jar C:\\BuildAgent"+jarDir);
final ExecResult result = SimpleCommandLineProcessRunner.runCommand(cmd, new byte[0]);
}

The following code worked for me.
final Runtime rTime = Runtime.getRuntime();
final Process process = rTime.exec("java -jar
C:\\TeamCity\\BuildAgent\\plugins\\teamcity-cutom-plugin-agent\\lib\\metrics-17.6.4.4.jar");
logger.progressMessage(new String(IOUtils.toByteArray(process.getInputStream())));
PrintStream printStream = new PrintStream(process.getOutputStream());
logger.progressMessage(new String(IOUtils.toByteArray(process.getErrorStream())));

Related

How to run a ReactJS application from Java code

I'm working on an application written in Java. The application is composed of many modules (maven). My task is to add a new module containing the application code written in ElectronJS and run it with Java code.
I did it this way.
private void turnOnElectronApp() {
ElectronAppRunner electronAppRunner = new ElectronAppRunner();
electronAppRunner.turnOnElectronApp();
}
public class ElectronAppRunner {
public void turnOnElectronApp() {
String user_dir = System.getProperty("user.dir");
user_dir += "/electron-app/src/main/electron-frontend-main";
System.out.println(user_dir);
String command = "npm start";
File workDir = new File(user_dir);
Runtime rt = Runtime.getRuntime();
try {
Process pr = rt.exec(command, null, workDir);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The application starts but the problem arises when building the project production version. Because user.dir is changing. How else can this be done?

Command Works Through Command Line, but Not When Using ProcessBuilder

I'm writing a program that includes a feature where the user can type in Java code into a text box and be able to compile and run it. The error I get is:
The two directories shown at the top are correct, and the command works when I do it manually through command prompt from the same working directory. I'm using Windows 10, and also here's the code:
public Process compile() throws IOException {
save(); //saves changes to source file
System.out.println(file.getCanonicalPath());
ProcessBuilder processBuilder = new ProcessBuilder("javac", file.getCanonicalPath());
processBuilder.directory(new File(settingsFile.getJdkPath()));
System.out.println(processBuilder.directory());
Process process = processBuilder.start(); //Throws exception
this.compiledFile = new File(file.getParentFile(), file.getName().replace(".java", ".class"));
return process;
}
File to compile:
Working directory:
Using this code, I was able to compile a Test.java file into a Test.class file on my Desktop.
import java.io.IOException;
public class App {
public static Process compile() throws IOException {
String myFilePath = "C:\\Users\\redacted\\Desktop\\Test.java";
String javacPath = "C:\\Program Files\\Java\\jdk1.8.0_171\\bin\\javac.exe";
ProcessBuilder processBuilder = new ProcessBuilder(javacPath, myFilePath);
return processBuilder.start();
}
public static void main(String[] args) throws IOException {
Process process = compile();
}
}
Using String javacPath = "javac.exe"; also worked, but that could be because my JDK bin is on my PATH variable.
There is something wrong with your paths or permissions in the ProcessBuilder constructor call.

How to start a JavaFX application in a standalone process

I'd like to start a JavaFX application, if it isn't already running.
The JavaFX application is packaged in a JAR container, which is in the classpath of the calling application. The calling application should execute the JavaFX app.
The JavaFX application should not terminate if the calling application gets terminated. (therefore it needs to be in a separate process)
I tried the following approach, but even though uiProcess.isAlive() returns true, the JavaFX application is never visible.
// caller main thread
String[] startOptions = new String[]{"java", "-jar", "javafx-ui.jar"};
Process uiProcess = new ProcessBuilder(startOptions).start();
+++++++++++++++++++++++++++++++++++++++
UPDATE:
I created a helper class which takes the JAR name and tries to execute it. Unfortunately this doesn't work. But if I copy the the logged CLI command and execute the command in a terminal, the app is started as expected. If I print System.getProperty("java.class.path") property, I see that my javafx-ui.jar is on the classpath.
Usage:
ProcessExecutor processExecutor = new ProcessExecutor();
processExecutor.executeJarByName("javafx-ui.jar");
Executor:
public class ProcessExecutor {
private List<Process> processes;
private static Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);
/**
* Default constructor
*/
public ProcessExecutor() {
processes = new ArrayList<>();
}
/**
* Executes jar in a standalone process
*
* #param jarName
*/
public Process executeJarByName(String jarName) throws IOException {
String[] command = new String[]{"java", "-jar", jarName};
ProcessBuilder builder = createProcessBuilder(command);
Process process = builder.start();
processes.add(process);
if (process.isAlive()) {
Optional<ProcessHandle> processHandle = ProcessHandle.of(process.pid());
if (processHandle.isPresent()) {
ProcessHandle.Info processInfo = processHandle.get().info();
logger.info("COMMAND: {}", processInfo.command().orElse(""));
logger.info("CLI: {}", processInfo.commandLine().orElse(""));
logger.info("USER: {}", processInfo.user().orElse(""));
logger.info("START TIME: {}", processInfo.startInstant().orElse(null));
logger.info("TOTAL CPU: {}", processInfo.totalCpuDuration().orElse(null));
}
}
return process;
}
private ProcessBuilder createProcessBuilder(String[] command) {
return new ProcessBuilder(command);
}
/**
* Kills all executed processes
*/
public void killAll() {
processes.forEach(p -> p.destroy());
}
}
I got it working, if I execute the following command, using the Java ProcessBuilder. The mainClassName needs to be the fully qualified class name of the class, containing the main() method. (including the package name)
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String javaHome = System.getProperty("java.home");
String java = javaHome + separator + "bin" + separator + "java";
String[] command = {java, "-cp", classpath, mainClassName};
ProcessBuilder builder = createProcessBuilder(command);

Unable to get output from Apache Commons Exec

Although the titles are very similar, this questions is NOT a duplicate of Process output from apache-commons exec.
I am trying to get the output of a command by using apache-commons exec. Here is what I am doing
import org.apache.commons.exec.*;
import java.io.ByteArrayOutputStream;
public class Sample {
private static void runCommand(String cmd) throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
CommandLine cl = CommandLine.parse(cmd);
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(psh);
exec.execute(cl);
System.out.println(stdout.toString());
}
public static void main(String... args) throws Exception {
String cmd1 = "python -c \"print(10)\"";
String cmd2 = "python -c \"import datetime; print(datetime.datetime.now())\"";
runCommand(cmd1); // prints 10
runCommand(cmd2); // should print the current datetime, but does not!
}
}
The problem is that runCommand(cmd2) does not print anything to the output. When I try running the command on terminal, it works fine.
I have tried this program with and without the IDE so I'm sure this has nothing to do with the IDE console.
Here's a screenshot
Here's a screenshot of the terminal
Python command running on the terminal
It works fine on mine PC from IDEA. Try to recreate the project. Add more information about your environment.
Try to put your python code into .py file and run it like "python test.py".
A colleague was able to come up with a solution to this problem. Changing
CommandLine cl = CommandLine.parse(cmd);
to
CommandLine cl = new CommandLine("/bin/sh");
cl.addArguments("-c");
cl.addArguments("'" + cmd + "'", false);
solved the issue.
The complete code looks as follows:
import org.apache.commons.exec.*;
import java.io.ByteArrayOutputStream;
public class Sample {
private static void runCommand(String cmd) throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
// CommandLine cl = CommandLine.parse(cmd);
CommandLine cl = new CommandLine("/bin/sh");
cl.addArguments("-c");
cl.addArguments("'" + cmd + "'", false);
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(psh);
exec.execute(cl);
System.out.println(stdout.toString());
}
public static void main(String[] args) throws Exception {
String cmd1 = "python -c \"print(10)\"";
String cmd2 = "python -c \"import datetime; print(datetime.datetime.now())\"";
runCommand(cmd1); // prints 10
runCommand(cmd2);
}
}

Unix executable changes to TextEdit document when copied

I have the following script, of which you can see below. The function of this Java script is to copy a Mac app, of which is placed in the same folder as the java program. It first finds the path of the folder, which the app and java program is in. It then copies all the content to the documents folder on the Mac device. When that is done it is then supposed to run that app of which it has copied to the documents folder.
The only issue is that it isn't able to do so. The reason being that whenever it copies the app, the JavaAppLauncher which is found within the content of the mac app has changed from a unix executable to a regular TextEdit document and thus can't actually launch the app. However if I were to copy the app manually by copying it myself and not using the java program, there is no issue. I am not sure whether this issue is caused by my code, or whether it is just a general thing?
Important note, the .app does work when I just run the regular non copied version, but as soon as it is the copied version, which as been copied through Java it doesn't work because the change of the Unix executable.
public class LaunchProg {
static String usernameMac2 = System.getProperty("user.name");
static File propFile = new File (".");
static String pathString = propFile.getAbsolutePath();
static int pathhLeng = pathString.length();
static int pathReaLeng = pathhLeng -1;
static String filNamMac = "AppNam.app";
static String pFPathRelMac = pathString.substring(0,pathReaLeng);
private static final File fSourceMac = new File(pFPathRelMac);
private static final File AppFold = new File ("/Users/" + usernameMac2 + "/Documents");
static File fileCret = new File("fCret.txt");
public static void main(String[] args) throws IOException {
System.out.println(pFPathRelMac);
launchMac();
}
static void launchMac() throws IOException {
if (!fileCret.exists()){
try {
FileUtils.copyDirectory(fSourceMac, AppFold);
PrintWriter pFW = new PrintWriter(fileCret);
pFW.println("Created File For Check");
pFW.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
String command = "open /Users/" + usernameMac2 + "/Documents/AppNam.app";
Process staAp2 = Runtime.getRuntime().exec(command);
}
}
}
}

Categories