Determine running classes and jar's from Linux ps output - java

My goal is to list to STDOUT the class files and .jar files being executed by java on a Linux server. I could do some getopts thing to get args to -jar, but other processes identified by
ps -ef | grep java or ps -eo args | grep java
might be executing a class file, e.g. java -classpath /a/b/c myclass A1 A2 . I am concerned that I am looking at an inelegant solution full of lengthy piplines of greps and awk's to solve what should be (I think) a straightforward query. Given that:
some calls are made to just 'java' and others to the fully qualified pathname for java,
a variety of different (or no) java options may be set on the command line for running a process,
some processes call .jar files, some call .class files, and
there may be args to the class,
what is the best way to get a simple list of running java executables, like:
abc.jar
mymainclass
xyz.jar
numainclass
I think that this may be a not uncommon question, but I can't seem to build a search string that locates any previous discussion here. An elegant solution would be nice; right now I am looking at grepping '-jar' entries to a getops call, and parsing the remainder considering all possible combinations. I am working on a solution in bash 3.x
Thanks!

The jps command introduced in jdk5 might be what you are looking for. Using the -l and -m options it will output the pid main class and arguments. Adding -v will add the vm arguments.

This option lists all Java files currently opened by a java command. Maybe it is useful to you.
lsof | grep -E "^java.*(.jar|.class)$" | sed -E "s/\s+/\t/g" | cut -f9
It works in Debian.

Related

LInux java class from process id pid

I am a newbie to linux. I am trying to find a command that displays
pid and java class.
I tried:
ps -C java -o pid
but it only showed me pid, not java classes.
So I used a different command:
ps -ef | grep java"
It showed me a full library of JAR files and associated java classes. However, I don't need all of that information, I need only to display pid and java class.
The problem that I am facing is that sometimes the java processes take like 100M of memory and I can only know the pid with the command java on it by using linux command:
top
But it couldn't find which java program is the one responsible for this. It will help me to debug that java file for memory leak.
ps aux | grep java
try this command and you can list of java process.
[or]
JPS will be helpful
JPS,JSTAT,JMAP,JSTACK,JHAT
you can run jps command it will show the pid value and based on these pid value others command will be executed.
Use java's jps command available from Sun Java.

Bash Script to run newest version of a file?

I'm using Apache Maven to release our product to Production, and as of right now, the resultant jar file that is created does not have a version number appended to it. I would like to append the current pom.xml version number (which I know how to do), but I need our installer script (basically a java -jar command with extra parameters) to access the newest version of the installer by default.
Say my deployment file is called foo.jar. My script is basically java -jar foo.jar
Instead, I'd like my deployment directory to contain foo-4.0.0.jar, foo-4.0.1.jar, foo-4.0.2.jar, etc.
I would like to create a bash script that runs the highest version of foo.
I've looked at sorting by creation date, but I can immediately think of scenarios that might not work out very well. I've considered doing it by date modified, and then manually touching the file that I want to install, but that idea kind of sucks too.
Clearly I need to split the name (probably with a regex) and isolate the version numbers (maybe substring from the last dash and the last period in the name?) and somehow sort them. The sorting is probably my biggest concern...that and reassociating the file.
If this is too complicated, I could theoretically make a Java file that does this (has it become clear that my primary language is Java?), but ideally it would just be a bash script.
Thanks
You can use sort, specifying the separator and set of keys to sort on e.g.
$ ls *.jar | sort -t- -k2 -V -r
will sort your jars in reverse (-r) using a version number (-V) sort, separating the version number from the jar name using -t-, and sorting on the second field using -k2 (your version number)
In my test directory I get:
a-2.2
a-2.1
a-2.0
a-1.50
a-1.10
a-1.3.1
c-1.3.0.1
a-1.3
a-1.2.9
b-1.2.8
a-1.2
which looks good.
Pipe the above through head -1 to give you the top entry.
Bash launcher script
Note: Verbose command options are used to make the script more reusable and easier to maintain.
#!/usr/bin/env bash
java -jar $(ls /home/opt/deployment_dir/*.jar \
|sort --version-sort --field-separator=- --key=2 --reverse \
|head --lines=1 \
)
Beware: Both the .jar file and above bash script should be rendered executable using the chmod +x command.

Classpath limitation in Linux

We are executing standalone java program from shell script, having a comman script to mention classpath, path, etc..In this common script, we have added several classpaths now and number of character is more than 9000.
It is working fine in the test env. Will it cause any issue in Production? Any limitation is there in linux to set classpath? What is the max char for command line inputs...
No, there is no limitation. In Windows there is (8191 characters), but not under Linux. We work with the concept of classpath-files. These file lists all the dependencies for the application, eg:
...
libs/org/easymock/easymock/2.2/easymock-2.2.jar
libs/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar
libs/org/hibernate/hibernate-envers/4.1.0.Final/hibernate-envers-4.1.0.Final.jar
libs/com/google/inject/guice/3.0/guice-3.0.jar
...
and then we convert this into usable classpath and run the application as follows:
#!/bin/bash
CLASSPATH_FILE=`ls -r1 ${APP-HOME}/classpaths/myapp*.classpath | head -n1`
CLASSPATH=$(cat $CLASSPATH_FILE | sed 's_^libs_ ${APP-HOME}/libs_' | tr -d '\n' | tr -d '\r' | sed 's_.jar/libs/_.jar:/libs/_g' | sed 's_.pom/libs/_.pom:/libs/_g')
java -d64 -cp $CLASSPATH com.blah.main.Main $#
We have never run into problems and these classpath entries gets pretty huge.
EDIT: As a side note, you can use the maven dependency plugin to generate a list of dependencies.
See this stackoverflow answer about maximum linux command line lengths.
The maximum command line length will be roughly between 128KB and 2MB.
The max size of any one argument is considerably smaller, though, and 9000 chars might be problematic.
When you use in your Java program some classes from a jar file that is specified in the classpath variable, the JVM won't load that class until your running program will explicitly need that class (or if you load that class explicitly from your code - the same idea). The only problem that can appear when you have a very long classpath, is the time needed for classpath checking before the JVM find the right jar file. But that should not be a problem. If your program behaves well in tests, you should not be worried about this.

Get the name of the java process instead of pid?

jps.exe which found on JDK 1.5 and later could monitor all Java process but is there a way to detect the specify command line and terminate the correct pid?
What if the user have JRE, is there a similar code allow us to terminate any process easily?
Prefer to keep the topic on Windows which I am working on.
The jps command supports a number of options that modify the output of the command. These options are subject to change or removal in the future.
-q Suppress the output of the class name, JAR file name, and arguments passed to the main method, producing only a list of local VM identifiers.
-m Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l Output the full package name for the application's main class or the full path name to the application's JAR file.
-v Output the arguments passed to the JVM.
-V Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags= argument).
Pipe the output of jps to grep or sed or awk or perl or even another Java program for further matching, parsing and action. On Windows, the easiest way to get those utilities is through Cygwin.
Here are some Microsoft downloadable command line utilities which are useful for working with processes on Windows:
pskill
pslist
and the rest of the Sysinternals Suite
If the user don't have jps, you can use ps. The command line options for ps differs between platforms, see man ps on you system. I use ps -C java -o pid,time,cmd to list java processes on a CentOS system. Then kill to terminate.

Linux command to find the which are the jars loaded by the jvm

Can someone let me know, what will be unix command if I need to check want are the jars loaded by java..
You can use lsof:
lsof -p <PID> | grep jar
use pgrep or jps to find the PID of your Java process.
You can use the option: java -verbose:class which shows what jars are being used
There are a couple ways to go about this.
From your java code you can call System.getProperty("java.class.path") which will return the whole classpath as a String.
You can also get the list by adding an argument on the command line java -verbose:class

Categories