I'm programmatically executing a java process via another java process in eclipse:
Process process = Runtime.getRuntime().exec(command, envp, dir);
Is there any way to tell eclipse to debug the child process?
Alternatively, I could solve this by chaining multiple launch configurations, ie launch process A, on completion launch process B - provided B could be launched in debug mode.
If you use the "Remote Debug" feature in Eclipse then you can point it at any JVM instance. You just need to make sure that each instance is told to use a unique JDWP port. This is how you'd do it from the command line:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=8998,server=y
So, change the 'address' part to whatever port you want, then you can point Eclipse at that port. Here's some more information:
http://java.dzone.com/articles/how-debug-remote-java-applicat
Add a command line option to the child process as follows:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=9999
(you can use a different port number than 9999, it's up to you, but best choose a number above 1024)
Then in Eclipse, create a Debug Configuration of type "Remote Java Application". Set the host as localhost and the port as 9999.
This developerWorks article has plenty of extra information.
EDIT: Incidentally for more flexibility in specifying the command line and environment of your child process, use the java.lang.ProcessBuilder class instead of Runtime.exec(...).
Related
I have a Java (Vert.x) application on my machine that I am trying to attach Eclipse to for debugging.
I usually start the Java application in my console like so:
java -jar build/libs/my-app.jar
Upon reading about debugging, I am attempting to start the app as follows:
java -jar build/libs/my-app.jar -Xdebug -Xrunjdwp:transort:transport=dt_socket,address=8001,server=y,suspend=n
The app seems to start up in the console fine when I run this.
I then go into Eclipse, and try to connect to the app via debugging via Run -> Debug Configurations. This is what my debug configuration looks like:
When I click debug, I get an error box that pops up and says that the connection is refused (I covered the name of my real app). See below:
What am I doing wrong? How can I get remote debugging to connect to my app with Eclipse?
According to my reading of this JDWP documentation, your -Xrunjdwp option is incorrect:
-Xrunjdwp:transort:transport=dt_socket,address=8001,server=y,suspend=n
should be
-Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n
If your system has multiple IP addresses, there could be some confusion about which IPs the agent is listening for connections on. You could force a specific address; e.g.
-Xrunjdwp:transport=dt_socket,address=127.0.0.1:8001,server=y,suspend=n
and use the matching IP and port in the Eclipse debug connection parameters.
AND ... as Dave Thompson spotted ... all JVM options must be placed before the -jar argument. (Anything after the -jar name.jar will be treated as command line arguments for your application.)
I'm trying to invoke a JMX MBean via Jconsole, but the method that I'm calling receive an object that needs to be on jconsole classpath in order to work.
I've tried this and the jconsole does not open (and no error is shown):
jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;path_to_newjar_\newjar.jar
Take jconsole.jar out of the -J classpath. It's already set in the jconsole launcher.
===== Update =====
Hmmm.... I take back my suggestion. I have a windows batch file I use [which works] which adds a JAR to the classpath. The intent is to add the JMXMP JMX client into jconsole and then launch to the argument specified JMX Service URL. It looks like this:
#echo off
start /B jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;MY-JAR-PATH\jmx-optional-1.0-b02-SNAPSHOT.jar service:jmx:jmxmp://localhost:%1
If a command like that does not work (i.e. jconsole still will not launch, but does not error out either), then you need to figure out where it is stalling. 2 suggestions for this:
Launch another jconsole and attach to the stalled jconsole by PID, switch to the Threads tab and eyeball what's going on in the main thread.
Or, (since it looks like you're in windows) hit Ctrl-Break and hopefully it will print out a thread dump to the console and you can then eyeball the main thread going-ons there.
Post back if you get anything (or if you don't....)
If you want to have access to both local & remote processes, the above answers are still missing a step.
From the Java 8 oracle docs:
If the JMX agent uses a connector which is not included in the Java platform, you need to add the connector classes to the class path when you run the jconsole command, as follows.
$ jconsole -J-Djava.class.path=JAVA_HOME/lib/jconsole.jar:JAVA_HOME/lib/tools.jar:connector-path
In the command above, connector-path is the directory or the Java archive (Jar) file containing the connector classes that are not included in the JDK, that are to be used by JConsole.
In your case, then, the command would be:
$ jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;%JAVA_HOME%/lib/tools.jar:path_to_newjar_\newjar.jar
When you leave off the JAVA_HOME/lib/tools.jar, local processes are no longer available.
Solution in Windows is to use quotes on your classpath, for example:
jconsole -J-Djava.class.path="%JAVA_HOME%\lib\jconsole.jar;path_to_newjar_\newjar.jar"
Does anyone know how to make eclipse or netbeans use the graphics card in optimus laptops by invoking optirun (bumblebee) inside the IDE so that one can just use the run button in the IDE to run the program in a graphics card within the IDE.
In simplest form I just want the IDE to do the equivalent of optirun ./javaproject
The way I did this in Eclipse was to first start the Java debugger jdwp and listen to a port. Then start the JVM with optirun java ... and use jdwp to connect to this port. Both tasks can be started at the same time in Eclipse by creating a Launch Group in the debug configuration settings (Run -> Debug Configurations). In detail:
Create a Remote Java Application debug configuration with "Standard (Socket Listen)" Connection Type and some arbitrary port, e.g. 56789. This attaches the Java debugger jdwp on port 56789 to a virtual machine which accepts debug connections at this port.
Now we need to start a JVM with optirun. This can be done with a External Tool Configuration (Run -> External Tools -> External Tool Configurations). Create a new Program configuration in the left side of the External Tools Configurations window. You could directly start optirun java <additional arguments> by filling in the required fields. However, I have decided to use a shell script which is reusable by different projects (As can be seen below, there is one part missing to make it entirely reusable. I'm glad for any help from more experienced Eclipse users...). Hence, the Location field points to this shell script. The script itself accepts three arguments: the classpath for the project, the name of the Java executable, and the port number. These arguments can be passed to the script in the Arguments field of the Main tab, e.g.
${project_classpath:${selected_resource_name}}
ExecName
56789
The shell script looks like this, assuming optirun is in your PATH:
#!/bin/sh
CLASS_PATH=${1}
JAVA_EXECUTABLE=${2}
PORT=${3}
# TODO: fix this java library path: pass it as an argument as well. Is there an Eclipse variable which stores this?
JAVA_LIBRARY_PATH=/usr/local/share/OpenCV/java
#------------------------------------------------------------------------------
optirun ${JAVA_BIN} -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:${PORT} -Djava.library.path=${JAVA_LIBRARY_PATH} -Dfile.encoding=UTF-8 -classpath ${CLASS_PATH} ${JAVA_EXECUTABLE}
#------------------------------------------------------------------------------
Finally, the two pieces are brought together in a Launch Group in the Debug Configurations window (Run -> Debug Configurations). Create a new Launch Group and add the two previously generated Debug configurations by clicking on Add in the Launches tab and by selecting the appropriate configurations.
Note that due to the classpath variable in step 2 (i.e. ${project_classpath:${selected_resource_name}}), the appropriate package needs to be selected in the Package Explorer before clicking on the run debug configuration button (make sure that the Launch Group is selected).
This solution works perfectly for me: I can debug Java code inside Eclipse which calls native code involving CUDA optimizations and Bumblebee only activates the discrete graphics card when necessary.
Just use optirun to start the IDE. For example, optirun eclipse or optirun netbeans
I build the project in Netbeans (F11) and run the following in a terminal:
optirun java -jar path/to/javaproject/dist/javaproject.jar
Mind that if you have any java parameters in your project, you need to add it manually. My workflow is like this:
Locate the Java options from the project, open Project -> Properties, Run. At VM Options I see -Djava.library.path=lwjgl/native/windows;:lwjgl/native/linux. I also have some parameters that I want to pass to main(String[]). With this information, I open a terminal and run:
cd path/to/javaproject
optirun java -Djava.library.path=lwjgl/native/windows;:lwjgl/native/linux \
-jar dist/javaproject.jar some paremeters
Another hint, if you have to open and close the program frequently, run optirun bash in a different tab so that preparing the use of the graphics card becomes faster. Alternatively, you can run optirun netbeans, but that means that the nvidia card will always be on even if you are programming which increases power use and increase the heat.
Important: if you are using a 32-bit JVM or Java libraries on a 64-bit machine, you also need to install the 32-bit drivers and libraries. For Ubuntu, the nvidia package already contains 32-bit drivers, see this answer. For other distros, you likely need to install lib32-* packages for Mesa, VirtualGL and nvidia-utils.
You can also rename java to java_real and use this portion of code as your java command :
#!/bin/bash
path=$(dirname $(readlink -f $0))
args=""
runner="$path/java_real"
for var in "$#"
do
if [ "$var" = "-3d" ]; then
runner="primusrun $runner"
else
args="$args $var"
fi
done
$runner $args
NOTE : I had to do this in /usr/lib/jvm/java-7-openjdk-amd64/jre/bin, not in /usr/bin to make it work with Eclipse.
In Eclipse, just add "-3d" in your program arguments and you're good to go !
I want to measure the code coverage of integration tests using the JaCoCo and Sonar tools.
For that, I start my Tomcat 5.5 configured with the JaCoCo agent in order to get the dump file from JaCoCo.
Thus, I set the JAVA_OPTS for that:
set JAVA_OPTS=-Xrs -XX:MaxPermSize=256m -XX:PermSize=256m -XX:NewRatio=3 -Xms512m -Xmx1024m -XX:+UseParallelGC -javaagent:C:\dev\servers\jacoco-agent.jar=destfile=C:\dev\servers\jacoco.exec,append=true,includes=my.application.*
When I start Tomcat, the C:\dev\servers\jacoco.exec file is generated, but no data is filled.
Is there something I forgot in the configuration of my server?
Regards.
I realize this may not have been an option 2 years ago when this question was asked, but presently you have some other options available to fetch the JaCoCo execution data without shutting down Tomcat (or any JVM instrumented with the JaCoCo java agent).
First take a look at the current documentation for the JaCoCo Java Agent: http://www.eclemma.org/jacoco/trunk/doc/agent.html
You can use the output=tcpserver option on the JaCoCo agent to have the Java agent listen for commands. You can set address=* to have the tcpserver listen on all interfaces, and you can set the port=6300 argument to choose the port where the tcpserver should listen.
Through the tcpserver the JaCoCo java agent can be instructed to send you the data whenever you ask for it.
If your JVM is currently exposing JMX you have another option which you can utilize without opening additional ports. By setting the jmx=true option the JaCoCo java agent exposes an MBean which you can interact with.
If you are using maven you can take a look at the plugin I recently wrote in order to gather JaCoCo data from remote JVM's while running. The project for the plugin is located at:
https://github.com/mattcj/jacocotogo
As far as I remember - file would be populated during shutdown of Tomcat.
Besides the maven solution, you can also consider https://www.eclemma.org/jacoco/trunk/doc/cli.html
Basically, you start your service on the remote machine with the javaagent option like (you can change the port number and omit includes if you want to have coverage for all of the classes):
-javaagent:/tmp/jacocoagent.jar=port=36320,destfile=jacoco-it.exec,output=tcpserver,includes=a.b.c.d.*”
Then connect to the remote machine by providing remote host address or open a tunnel to the remote machine. The following example assumes I have set up a port forwarding between local host's 36320 and remote host's 36320
java -jar jacococli.jar dump --port 36320 --destfile /tmp/jacoco-it.exec
If you have multiple .exec files, you need to merge them:
java -jar jacococli.jar merge /tmp/jacoco-it-1.exec /tmp/jacoco-it-2.exec --destfile /tmp/merge
Then generate the html report (path1 can be a path to the jar file or the class files folder)
java -jar jacococli.jar report /tmp/jacoco-it.exec --classfiles path1 --sourcefiles path2 --html /tmp/report
I have a java application running on linux machine. I run the java application using the following:
java myapp -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000, suspend=n
I have opened port 4000 for TCP on this Linux machine. I use eclipse from Windows XP machine and try to connect to this application. I have opened the port in windows also.
Both machines are on the LAN but I can't seem to connect the debugger to the Java application. What am I doing wrong?
Edit: I noticed that some people are cutting and pasting the invocation here. The answer I originally gave was relevant for the OP only. Here's a more modern invocation style (including using the more conventional port of 8000):
java -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n <other arguments>
Original answer follows.
Try this:
java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n myapp
Two points here:
No spaces in the runjdwp option.
Options come before the class name. Any arguments you have after the class name are arguments to your program!
For JDK 1.3 or earlier :
-Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6006
For JDK 1.4
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6006
For newer JDK :
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6006
Please change the port number based on your needs.
From java technotes
From 5.0 onwards the -agentlib:jdwp option is used to load and specify
options to the JDWP agent. For releases prior to 5.0, the -Xdebug and
-Xrunjdwp options are used (the 5.0 implementation also supports the -Xdebug and -Xrunjdwp options but the newer -agentlib:jdwp option is preferable as the JDWP agent in 5.0 uses the JVM TI interface to the
VM rather than the older JVMDI interface)
One more thing to note, from JVM Tool interface documentation:
JVM TI was introduced at JDK 5.0. JVM TI replaces the Java Virtual Machine Profiler Interface (JVMPI) and the Java Virtual Machine Debug Interface (JVMDI) which, as of JDK 6, are no longer provided.
Answer covering Java >= 9:
For Java 9+, the JVM option needs a slight change by prefixing the address with the IP address of the machine hosting the JVM, or just *:
-agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,suspend=n
This is due to a change noted in https://www.oracle.com/java/technologies/javase/9-all-relnotes.html#JDK-8041435.
For Java < 9, the port number is enough to connect.
Steps:
Start your remote java application with debugging options as said in above post.
Configure Eclipse for remote debugging by specifying host and port.
Start remote debugging in Eclipse and wait for connection to succeed.
Setup breakpoint and debug.
If you want to debug from start of application use suspend=y , this will keep remote application suspended until you connect from eclipse.
See Step by Step guide on Java remote debugging for full details.
I'd like to emphasize that order of arguments is important.
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar app.jar command opens debugger port,
but java -jar app.jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 command doesn't. It will pass everything after app.jar as command-line arguments.
This is how you should setup Eclipse Debugger for remote debugging:
Eclipse Settings:
1.Click the Run Button
2.Select the Debug Configurations
3.Select the “Remote Java Application”
4.New Configuration
Name : GatewayPortalProject
Project : GatewayPortal-portlet
Connection Type: Socket Attach
Connection Properties:
i) localhost ii) 8787
For JBoss:
1.Change the /path/toJboss/jboss-eap-6.1/bin/standalone.conf in your vm as follows:
Uncomment the following line by removing the #:
JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"
For Tomcat :
In catalina.bat file :
Step 1:
CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
Step 2:
JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
Step 3: Run Tomcat from command prompt like below:
catalina.sh jpda start
Then you need to set breakpoints in the Java classes you desire to debug.
for everybody that has the problem that if you really do remote debugging from 1 machine to the other then using :
-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n
is not enough because that binds now (at least on unix/osx machines) to localhost so you can only connect to it from localhost.
If you try to remote debug this then you will get connection refused for this. From i think Java 9 on you need to do:
-agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,suspend=n
or give an ip that it needs to bind on for hat *