Java - get PID of external process by command line in Windows 7 - java

I have Windows 7 32 bit with Java:
How do I get the PID of a process by command line in Windows 7?
I want to kill an application which I only can truly identify by the command line which ran it. We have several Java applications running on that machine. I need to stop specific ones.
To be exact: I need to find tomcat which is run by catalina.bat. What do you think is the best way to do this?
I know of tasklist, but it does not seem to be able to query the command line which started the process. Finding java.exe does not help me. I tried searching for something useful like pgrep/pkill for Windows, with no success.

You could use jps -lv command to determine java process by it's command line options. jps is utility that included in many up-to-date JDKs.

Try in a command prompt:
sc queryex type= service state= all | find "APP"
Where APP is the name of the program. This command will return all services that match that.
Then you can run SC QUERYEX APP and it will return the state and PID number.
Once you have the PID:
TASKKILL /f /pid ###
Where ### is the actual PID

Java, get the PID of the current running process in Windows
This should work on Linux, OSX, Windows, and HotSpot JVM's.
import sun.management.VMManagement;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public static int getCurrentPID() {
try{
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
return (Integer) pid_method.invoke(mgmt);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Failed at getting the process ID");
System.exit(0);
}
}
Invoke it like this:
System.out.println("PID: " + getCurrentPID());
For me it prints the processID: PID: 5728
Sources:
How can a Java program get its own process ID?
http://boxysystems.com/index.php/java-tip-find-process-id-of-running-java-process/

If you just need to kill a specific tomcat from a java application why not coding a simple servlet running inside each tomcat that will responde to a get request with a string that will identify it. Then use another servlet to execute something like:
System.exit(-1);

Finally found something. The solution working for me is called wmic (Windows Management Instrumentation Commandline). This nice tool comes built-in to Windows 7 Pro (mine) and possibly other Windows versions. It provides a quite large variety of actions like listing all the running tasks with every details you can imagine (like their corresponding command line), various hardware info, etc. Exactly what I need.

Related

Can't execute java code within flask application using os.system()

I have been trying to solve this issue for 5 hours
when I try to execute the below code in the terminal it works fine. However, when I use the same code in flask application I am getting this error (sh: 1: java: not found)
import os
environ = os.environ.copy()
os.putenv("JAVA_HOME", "/usr/lib/jvm/java-14-oracle/bin/java")
os.environ["PATH"] += os.pathsep + ":/usr/lib/jvm/java-14-oracle/bin/java/bin"
os.system("java -jar /home/../myproject/application/graphseg1.jar /home/../myproject/application/entire_text /home/.../myproject/application/segmented_text 0.40 2")
the above code works fine within the terminal as shown below:
However, when I try to run the same code within flask application, I am getting the following error:
I am using Ubuntu 18.04, nginx,supervisor,gunicorn3
supervisor configration file:
[program:flask_app]
directory=/home/****/myproject
environment=PATH=/tmp/enter/envs/myenvi/bin
command=/tmp/enter/envs/myenvi/bin/gunicorn application:app --timeout 9223372036
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/flask_app/flask_app.err.log
stdout_logfile=/var/log/flask_app/flask_app.out.log
You should probably using Subprocess instead. It provides pipes for STDIN, STOUT, STDERR and the option for a full shell with some inherent security warnings.
See: https://docs.python.org/2/library/subprocess.html#module-subprocess
Seems like your path is not setup properly, like omajd said can you print it?
See also: Problems adding path and calling external program from Python

Why doesn't cd command work using Java JSch?

I'm just learning Java and Jsch, and I can get it to run other commands but not cd. The error code returned by the SSHManager sendCommand function is not null, but some unreadable string that is different every time (maybe that means it is null not that familiar with inner workings of Java).
Any idea why not? Similar question here JSch - Why doesn't CD work? but unanswered.
I won't copy and paste the whole SSHManager class here - useful answer with complete code here that I'm trying to follow. Run a command over SSH with JSch
Sample code below:
import SSH.SSHManager;
public class src
{
int ERROR = 0;
public static void main(String[] args)
{
String username = "debian";
String password = "temppwd";
String ipadd = "192.168.7.2";
SSHManager ssh = new SSHManager(username, password, ipadd, "");
ssh.connect();
String out = "";
//this doesn't work, printing output as bytes to show how weird it is
out = ssh.sendCommand("cd Desktop");
System.out.println(out.getBytes());
//some other test commands
out = ssh.sendCommand("mkdir test");
System.out.println(out);
out = ssh.sendCommand("ls");
System.out.println(out);
ssh.sendCommand("logout");
}
}
Output from the Eclipse Console (bin and Desktop are already there in root directory):
[B#b065c63
bin
Desktop
test
Each command executed over SSH "exec" channel (what is behind SSHManager.sendCommand) is executed in its own shell. So the commands have no effect on each other.
To execute multiple commands in the same shell, just use an appropriate syntax of your server shell. Most *nix shells use semicolon or double-ampersand (with a different semantics).
In your case, the double-ampersand would be more appropriate.
cd Desktop && mkdir test && ls
See also Multiple commands using JSch.
Though, if your want to read commands output, you will have problem distinguishing, where output of one commands ends and output of the following commands starts. Let alone if you wanted to check command exit code.
Then it's better to execute each command in its own "exec" channel in a way that does not require a context. In your case that means using full paths:
mkdir Desktop/test
ls Desktop
See also How to perform multiple operations with JSch.
Also as you were going to use file manipulation only, you actually should not execute shell commands at all. Use the standard SSH API for file manipulation, the SFTP.
The question has kind of an answer, in the comments. Every command in sendCommand uses it's own 'pipe', so it disconnects and starts over in each one.
A quick solution would be to send multiple commands in one one sendCommand, such as:
out = ssh.sendCommand("cd Desktop; mkdir test; ls; logout");
But the correct way is to use a session, such as https://stackoverflow.com/a/9269234/290036
I answered a similar question Using java jcabi SSH client (or other) to execute several commands in shell
My open-source API Maverick Synergy has a high-level API to execute multiple commands within a shell. Its currently designed for and works well with bash-type shells.

How to check if a class is loaded or not in a Java process

My task is to find out how many springboot app are running on a Linux system.
So What I am planning to do is,
1. to get all the java process IDs
$ ps -aux|grep java
2. Then somehow get the loaded classes from the IDs.
I don't know if it is possible or not. Someone please kind enough to guide me to the right direction?
P.S. : I am using java to run the above command by the help of Process class, something like this :
Process process = Runtime.getRuntime().exec("ps -ef");
So I want to do it from a java project.
I came to this page searching for a recipe "how to find if a jar has been loaded" (which is a bit different than the original question). But perhaps it will be useful for somebody:
I found jcmd as best way to get this info, for example:
I have a running JVM with PID 1 (it's a CN application started in K8s):
$ jps
1 MyAppLauncher
529 Jps
Figure out what options jcmd provides for this JVM:
[eceuser#ecs1-0 temp]$ jcmd 1 help
1:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
With a bit of try and error, I found that VM.dynlibs does what I needed:
$ jcmd 1 VM.dynlibs | grep custom
7f59a4b3b000-7f59a4b3d000 r--s 00000000 fd:00 1116085962 /home/app/lib/custom-fi-extensions-0.0.1-SNAPSHOT.jar
So yes, this jar has been loaded.
You need to put some sort of identifier into your app's startup command line. E.g. something like:
String id = "com.app.demo";
When you run your app, make sure to include the string. Let's say you start it from within Java, do the following:
Runtime.getRuntime().exec("C:\...\javaw.exe -cp ... -Dwhatever=" + id + " com.app.app.demo.Main");
Get the application by id like $ps aux | grep -i com.app.app.demo. In Java call Runtime.getRuntime().exec("ps aux | grep -i com.app.app.demo");
I would prefer using ProcessBuilder instead(from Java 8), and running your command via bash:
Process process = new ProcessBuilder().command("bash", "ps aux | grep com.app.app.demo").start()
Hope this gives an idea.
Quick and dirty method: some static block into your class and in it print something into a log (or system.out). Static block is executed when class is loaded by class loader and not when the first instance instantiated (this is when constructor is called for the first time). Then if your printout is in the log then the class has been loaded. Example:
public class Sample {
private static final Logger logger = ...
static {
logger.info("class Sample is loaded");
}
...
}
Assuming you can identify some specific class which determines if the application is a springboot application, you could use some tool from the jdk, which can output loaded classes. I've tried it with jcmd(you'll find it under jre/bin/):
I'm not very good with bash so it might be not very efficient, but this works for me assuming that every springboot application has loaded class org.springframework.boot.logging.LoggingInitializationContext and no non-springboot app loads it.
ps aux | grep [j]ava | awk '{print $2}' | xargs -I{} jcmd {} VM.class_hierarchy | grep "org.springframework.boot.logging.LoggingInitializationContext"
It finds processes containing java, takes only the PID, passes it to the jcmd where you grep for the specific class. The output seems to be correct, the only problem is that I loose the PID in this long pipe and I'm not sure how to print it.
But if your problem is "how many springboot apps", then it might not be an issue. I'm also not sure if the classes may appear twice when using jcmd VM.class_hierarchy, but it doesn't look like it.
Note: This works on JDK 11. I tried jmap first, but that doesn't work for me on JDK 11 for some reason.

Use docker-machine create from java

I have an application that (I want to) uses Java to start and stop Docker containers. It seems that the way to do this is using docker-machine create, which works fine when I test from the command line.
However, when running using Commons-Exec from Java I get the error:
(aa4567c1-058f-46ae-9e97-56fb8b45211c) Creating SSH key...
Error creating machine: Error in driver during machine creation: /usr/local/bin/VBoxManage modifyvm aa4567c1-058f-46ae-9e97-56fb8b45211c --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 on --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd failed:
VBoxManage: error: Could not find a registered machine with UUID {aa4567c1-058f-46ae-9e97-56fb8b45211c}
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee nsISupports
VBoxManage: error: Context: "FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())" at line 500 of file VBoxManageModifyVM.cpp
I have set my VBOX_USER_HOME variable in an initializationScript that I'm using to start the machine:
export WORKERID=$1
export VBOX_USER_HOME=/Users/me/Library/VirtualBox
# create the machine
docker-machine create $WORKERID && \ # create the worker using docker-machine
eval $(docker-machine env $WORKERID) && \ # load the env of the newly created machine
docker run -d myimage
And I'm executing this from Java via the Commons Exec CommandLine class:
CommandLine cmdline = new CommandLine("/bin/sh");
cmdline.addArgument(initializeWorkerScript.getAbsolutePath());
cmdline.addArgument("test");
Executor executor = new DefaultExecutor();
If there is another library that can interface with docker-machine from Java I'm happy to use that, or to change out Commons Exec if that's the issue (though I don't understand why). The basic requirement is that I have some way to get docker-machine to create a machine using Java and then later to be able to use docker-machine to stop that machine.
As it turns out the example that I posted should work, the issue that I was having is that I was provisioning machines with a UUID name. That name contained dash (-) characters which apparently break VBoxManage. This might be because of some kind of path problem but I'm just speculating. When I changed my UUID to have dot (.) instead of dash it loaded and started the machine just fine.
I'm happy to remove this post if the moderators want, but will leave it up here in case people are looking for solutions to problems with docker-machine create naming issues.

schtasks : ERROR: Incorrect Start Date

I am using "schtasks" to create a task in the windows task Scheduler. Below is the command that am using.
"SchTasks /Create /TN CRM_TELESMART_ICE /TR "perl D:\Serviont\LSS-Phase2\hdfc_Perl\bin\common_processing.pl --sourcename CRM_TELESMART_ICE --type DB" /SD 06/23/2016 /ST 12:38 /SC MINUTE /MO 20 /F "
Here the problem is, when I run this java file it executes well and creates a task in local machine. In server it is showing the below error.
Process exiting with code: -2147467259
ERROR: Incorrect Start Date.
I tried to create the same via a standalone java application it is working in server too. The only problem is, when calling through the production application.
Can someone help me on this ?
Old question I know but have you tried using a sensible date such as 23/06/2016? Possibly the regional settings in your Java file are set to something other than American somehow.

Categories

Resources