I have an obfuscated Java 8 program and I want to attach a Java agent to it. But when I start it with java -javaagent:intrace-agent.jar -jar program.jar it launches and disattaches from the console after a few seconds, my agent finishes. If I try to see program's command line args in Process Explorer, there's a -XX:+DisableAttachMechanism option (this program adds it during startup somehow). Are there any ways to bypass that?
Thanks in advance!
There's two approaches you can take to get around that:
Modify the program's bytecode to make it not relaunch itself like that.
Get the OpenJDK source, remove the check that makes that option do anything, and then run the program in that environment.
Note that with either of those approaches, the program might end up noticing that you did it and doing something else to foil you.
Related
I have created a Java program which reads encrypted files from local system and does some processing. Actually I have 20 files to read so I have used threading mechanism to speed up the program execution.
When I run the program in Eclipse it takes more than 30 minutes to complete the execution, whereas if I make a runnable jar and execute the program using command prompt, it takes less than a minute.
Why does running programs in Eclipse take more time than running them in command prompt?
Eclipse's Console view that captures System.out is notoriously slow compared to the regular stdout of the command line. Whenever there is a lot of printing happening in the program, it is to be expected that the program will run significantly slower from Eclipse.
But anyway, unless you are writing a program designed to integrate with other programs via Unix pipes, you should minimize the printing as it will kill performance even at the command line.
There are some typical mistakes:
Maybe you are executing your program in Debug mode.
Try to use Run (play symbol inside a green circle) instead of Debug (a green bug)
Maybe you are executing your program with a different JVM
Take a look in Project Properties->Java compiler, Window->Preferences->Java->Compiler and Window->Preferences->Java->Installed JREs
The output and input interactions with Java Console of Eclipse JDT differ on performance than standard console.
Ensure that you use the Run action in Eclipse, and not Debug, as the latter really has measurable difference, especially if you use conditional breakpoints.
However, I remember having less significant differences arising from the use of the Debug.
I have just did an experiment for you and did not saw so significant difference.
I created class that calculates sin() 100000000 times.
This program ran ~15 seconds under eclipse and ~14 seconds via command prompt.
So, here are the reasons for slowness in your system I can see at the top of my head:
Be sure that you are not running under debug. Use Run option, not Debug.
Be sure that you do not have some coverage/monitoring developers tools on under eclipse. For example YourKit, Emma etc.
Be sure that your program does not produce significant prints to the console.
Check that you have enough heap memory when running under eclipse
Changing jdk 6 to jdk 7 worked perfectly for me.
Window->Preferences->Java->Installed JREs
Can someone explain to me how to monitor the garbace collector (GC) in Java as if I'm five years old?
Everything I read about it says to use the command line, but I don't really understand where, when or how to do that. I understand how to get the command window up, but I'm using Eclipse, and they don't really connect.
So when I see this:
-verbose:gc -XX:+PrintGCTimeStamps
Since I am not running my compiler from the command line: how would I use this in Eclipse? Every resource I reach from Google assumes I know how to use that.
There is really no such thing as the garbage collector when you are invoking the compiler.
Assuming you are asking about how to set these options when you execute your application within Eclipse, then you want to add these as VM arguments in the Run dialog, as in the highlighted text in this screenshot.
I've got a (fairly typical) setup at the moment of launching my Java application through a batch file calling the jar file with appropriate parameters, which most of the time works absolutely fine. However, I'd like to be able to deal with any errors that might occur nicely.
At the moment I've got something like
java -Xms1024m -Xmx1024m -jar Quelea.jar
IF NOT (%ERRORLEVEL% == 0) cscript MessageBox.vbs "Application failed to start."
The last line is basically the first answer on this question.
I'd like something a bit more fully featured though, even if it's a case of capturing the output from launching the process and then dumping it in the message box (ok, it's not pretty but it shouldn't appear to start with and when it does appear that then gives me some immediate debugging information without having to ask the user to grab out log files!) Or are there any other approaches that people use in similar situations?
I'm not talking about exceptions thrown in my code (which I deal with once the application starts) I'm talking about hard errors that prevent it starting such as using an old JRE version, not having enough memory to reserve for heap, that sort of thing.
I suggest using a Java executable wrapper. I like the following, but there are others.
http://launch4j.sourceforge.net/
I've a bash script that sequentially calls a java program. That's a bit tricky but mainly what i do is to have a loop and executes about 1500 times the same java program with different arguments.
My question is, when using java 1.5 (the sun VM), each time I'm calling the java program a new instance of the jvm is created ? (I'm not sure that's the right vocabulary...)
Should I avoid this situation by introducing a level of indirection, i.e building a list of all the parameters and then executing one java program which takes these parameters and executes what was previously my entry point ?
Or can I deal with the problem by configuring the JVM as resident or something like that and dynamically invokes my program....
hope this is clear....
thx...
You could save the parameters into a file and use the Java program to process it without constant restart. You could also pipe in the parameters into the running Java app through the console, similarly as for example ls | grep java
Edit: And for the first question. I doubt the java runtime would stay deliberately in memory. Probably most JRE files would remain in the disk cache anyway. On Windows there is a Java Quick Start service which keeps the JRE files around to reduce the startup time for a java program. Don't know whether there is a similar thing for *nix.
Obviously having all the parameters beforehand and running the program once after that would be the best solution. If you cannot do that for any reason i have a very dirty solution to this. Have your program register a port and listen to it for input. Then simply pass the arguments to that port and have your program handle them as a new instance.
JVM startup is notoriously slow, and it certainly not intended to be done in a loop like that. Unfortunately the only way to avoid this if you are passing command line parameters to the java program is to modify the java program itself in some way to have alternative forms of interaction (either from the console, or a port, or a read a file). Java Quick Start is the only (closest thing to a) solution if the java program cannot be changed.
The real solution is to change the Java program. The most obvious change would be to have your loop write to a file, and then start the java program that would read the file one line at a time. That works if the loop doesn't care about the results from the java program for the next set of parameters.
If it does, then it would really be necessary to understand that relationship to advise on an appropriate solution. The socket solution suggested by Savvas is certain a general purpose solution, but there may be better options, depending on what you need to accomplish.
You can use a launcher like in the answer to
Simultaneously run java programs run on same JVM? to read input line by line and start your program's main() method.
anyone have any experience using this?
if so, is it worth while?
I just used jdb for the first time yesterday and am really pleased with the results. You see, I program in Eclipse on my laptop, then deploy to a VM to make sure the whole shebang still works. Very occasionaly, I'll have to work on something that gets executed standalone, as a commandline. These things sometimes need debugging.
This has always been a problem, because I don't want to go to the trouble of installing Eclipse on the VM (it's slow enough already!), yet I don't know of an easy way to get it to connect to my commandline-running class before it finishes running.
jdb to the rescue! It works a treat - small and functional, almost to the point where it is bare... this forces you to apply your mind more than you apply the tool (like I said here).
Make sure to print out the reference (solaris, windows, java 1.5 - I think they're all about the same, really) and have your source code open and browsable on your second screen. I hope you have a second screen, or you'll be alt-tabbing a lot.
Assume your program is started by the following command:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=<port> <class>
You can attach to this process by jdb:
jdb -attach <port>
In some cases you need to use the following command .
jdb -sourcepath \.src -connect com.sun.jdi.SocketAttach:hostname=localhost,port= <port>
JDB is incredibly difficult to use. Placing System.outs or using an IDE debugger will produce better results. And for the more interesting features (e.g. tracking threads, heap size, etc.), you can get the information graphically with the JConsole tool.