Running code in Java Agents after the execution? post main? - java

I'm working with Java Agent (creating a profiler) using code instrumentation (using Javassist for Instrumentation). I need to run few functions in my Java Agent profiler after the complete execution of java program. Something after the main function, like post-main (like we have premain). Is that possible?

There is no such thing as a postmain method and its semantics would not be clear either. Many programs run until they are killed. This requires the application to terminate and not to run different code.
Java offers shutdown hooks via the Runtime class that are triggered on an application's termination but which must not perform long-lasting operations. Also, they are not executed if a program is killed.
For a profiler, you would need to process data regularly and you could attempt to flush your buffers on termination without a guarantee.

Related

What happens if I call a java function from multiple threads from C with JNI?

This link seems to suggest that "it just works": (pretty far on the bottom under 7.3 Attaching Native Threads) http://java.sun.com/docs/books/jni/html/invoke.html
I don't see how that is possible, is the embedded JVM going to start its own threads automatically? Or queue the JNI calls? How else could there be multiple calls to the same virtual machine. which I haven't instructed to do any threading?
Any way I can imagine that to work is, if the java code will simply be executed in the same calling thread as the c code. Is that correct? That would mean that I don't have to do any threading in Java.
The jvm does not have to create its own threads, the method calls are executed on the native threads that make them. The AttachCurrentThread and DetachCurrentThread will take care of any necessary jvm internal state management, for example creating java Thread objects wrapping the native threads.
The JVM starts its own threads which it needs to run. You trigger this thread creation by starting the JVM.

Kill / Stop an application with Java Code

Is it possible to stop an application in windows using java code ?
I'd like to create a program which is like a shortcut to stop an application on my pc. Is it possible using ProcessBuilder ? Thank you
Plain Java, without native access? No.
ProcessBuilder lets you control processes that you started from within the Java application, but it doesn't give you control to processes that were started by other processes.
As per user988052's comment, you can use pskill from the Sysinternals Suite to accomplish this through Runtime.exec. pskill uses the TerminateProcess function call. You can also call this function with JNI (or some other native caller, like JNA, NLink, etc.), but you'll need to obtain a handle to the process via the OpenProcess function call.
Is it possible to stop an application in windows using java code ? ... Is it possible using ProcessBuilder ?
Only if you launched the application from the same Java application that you are trying to fill it from.
Other than that, you need to resort to running a Windows-specific command to do the killing ... or something based on JNI to make native Windows library calls.
The other complications are that you may not be able to kill certain processes due to permissions issues, and some process may refuse to be killed.
I believe the JRE does not provide an API for system processes. ProcessBuilder can create system processes, but it cannot provide you with a Process object for a process created outside the JVM. I believe that is a philosophical decision on the part of the Java folks, to avoid certain OS-specific tasks where possible. You might think that every OS has pids, or that they all have some kind of kill message, but Java runs on lots of OSes, some of them quite strange.
You could make native code to do it and wrap that with JNI, but that would be wasteful. As Mr 988052 says, I suggest you execute a system-specific command through Runtime.exec or ProcessBuilder. You would need to decide which OSes you want to support, and be sure to get the commands (and the OS-detection code) right for each one.

Ensure program runned via Runtime.exec() will die together with the java app

in my java program I am calling external program via Runtime.exec and calling Process.waitFor to wait for its completion. This is some long-running script. I want to ensure that if anything goes wrong with my java app (e.g. gets killed from outside for example, which btw. really happens from time to time in my case) the external running script will die as well.
I had a look on the Runtime.addShutdownHook which might be appropriate for this, but it clearly states that for example on SIGKILL no guarantee can be made whether the shutdownhook will or won't run.
Is there any other way how to ensure an external program runned from Java will die together with the calling java process?
Thanks
If "Runtime.addShutdownHook" is not sufficien I think from the java side you are out of luck. Some ideas:
your script can test if the java app is still running and terminating if needed
let your java app update a file with a timestamp and let your script check periodically if the timestamp is to old (and terminate)
Edit: launch another process which only monitors the java app and the script and kills the script is the java app is gone (of course if THIS process is killed you are out of luck again)

Java exit a program without quitting JVM

I want to exit a java process and free all the resources before it finishes its normal running, if a certain condition is meet. I dont however want to quit JVM, as I have other java programs running at the same time. Does return; do the above, or is there a better way to do it?
Thanks.
There is one JVM process per running Java application. If you exit that application, the process's JVM gets shut down. However, this does not affect other Java processes.
You need to understand the JVM mechanism and clarify the terminology.
Let's use the following as datum for the terminology.
Threads are divisions of concurrently processed flows within a process.
A process is an OS level thread. The OS manages the processes. A process is terminated by sending a termination signal to the OS management. The signal may be sent by the process itself or by another process that has the applicable privilege.
Within a process, you can create process level threads. Process level threads are normally facilitated by the process management of the OS, but they are initiated by the process and terminated by the process. Therefore, process level threads are not the same as processes.
An application is a collection of systems, programs and/or threads that cooperate in various forms. A program or process within an application may terminate without terminating the whole application.
Within the context of JVM terminology, program may be one of the following.
A program is run per JVM process. Each program consumes one JVM process and is invoked by supplying the classpath of java bytecode and specifying the main entry point found in the classpath. When you terminate a java program, the whole jvm process that ran that program also terminates.
A program is run per process level thread. For example, an application run within a tomcat or JEE server is run as a thread within the JEE process. The JEE process is itself a program consuming one JVM process. When you terminate an application program, the JEE process does not terminate.
You may initiate process level threads within a java program. You may write code that terminates a thread but that would not terminate the process (unless it is the last and only running thread in the process). The JVM garbage collection would take care of freeing of resources and you do not need to free resources yourself after a process level thread is terminated.
The above response is simplified for comprehension. Please read up on OS design and threading to facilitate a better understanding of processes and the JVM mechanism.
If the other threads running concurrently are not daemon threads, leaving main will not terminate the VM. The other threads will continue running.
I completely missed the point though.
If you start each program in a separate JVM, calling System.exit() in one of them will not influence the others, they're entirely different processes.
If you're starting them through a single script or something, depending on how it is written, something else could be killing the other processes. Without precise information about how you start these apps, there's really no telling what is going on.
#aix's answer is probably apropos to your question. Each time you run the java command (or the equivalent) you get a different JVM instance. Calling System.exit() in one JVM instance won't cause other JVM instances to exit. (Try it and see!)
It is possible to create a framework in which you do run multiple programs within the same JVM. Indeed this is effectively what you do when you run a "bean shell". The same sort of thing happens when your "programs" are services (or webapps, or whatever you call them) running in some application server framework.
The bad news is that if you do this kind of thing, there is no entirely reliable way make an individual "program" go away. In particular, if the program is not designed to be cooperative (e.g. if it doesn't check for interrupts), you will have to resort to the DEPRECATED Thread.stop() method and friends. And those methods can have nasty consequences for the JVM and the other programs running in it.
In theory, the solution to that problem is to use Isolates. Unfortunately, I don't think that any mainstream JVMs support Isolates.
Some common usecases leading these kind of requirements can be solved through tools like Nailgun, or Drip.
Nailgun allows you to run what appears to be multiple independent executions of a commandline program, but they all happen in the same JVM. Therefore repeated JVM start-up time does not have to be endured. If these execution interact with global state, then the JVM will get polluted in time and things start to break up.
Drip will use a new JVM for each execution, but it always keeps a precreated JVM with the correct classpath and options ready. This is less performant, but it can guarantee correctness through isolation.

JDK 6: Is there a way to run a new java process that executes the main method of a specified class

I'm trying to develop an application that just before quit has to run a new daemon process to execute the main method of a class.
I require that after the main application quits the daemon process must still be in execution.
It is a Java Stored Procedure running on Oracle DB so I can't use Runtime.exec because I can't locate the java class from the Operating System Shell because it's defined in database structures instead of file system files.
In particular the desired behavior should be that during a remote database session I should be able to
call the first java method that runs the daemon process and quits leaving the daemon process in execution state
and then (having the daemon process up and the session control, because the last call terminated) consequentially
call a method that communicates with the daemon process (that finally quits at the end of the communication)
Is this possible?
Thanks
Update
My exact need is to create and load (reaching the best performances) a big text file into the database supposing that the host doesn't have file transfer services from a Java JDK6 client application connecting to Oracle 11gR1 DB using JDBC-11G oci driver.
I already developed a working solution by calling a procedure that stores into a file the LOB(large database object) given as input, but such a method uses too many intermediate structures that I want to avoid.
So I thought about creating a ServerSocket on the DB with a first call and later connect to it and establish the data transfer with a direct and fast communication.
The problem I encountered comes out because the java procedure that creates the ServerSocket can't quit and leave an executing Thread/Process listening on that Socket and the client, to be sure that the ServerSocket has been created, can't run a separate Thread to handle the rest of the job.
Hope to be clear
I'd be surprised if this was possible. In effect you'd be able to saturate the DB Server machine with an indefinite number of daemon processes.
If such a thing is possible the technique is likely to be Oracle-specific.
Perhaps you could achieve your desired effect using database triggers, or other such event driven Database capabilities.
I'd recommend explaining the exact problem you are trying to solve, why do you need a daemon? My instict is that trying to manage your daemon's life is going to get horribly complex. You may well need to deal with problems such as preventing two instances being launched, unexpected termination of the daemon, taking daemon down when maintenance is needed. This sort of stuff can get really messy.
If, for example, you want to run some Java code every hour then almost certanly there are simpler ways to achieve that effect. Operating systems and databases tend to have nice methods for initiating work at desired times. So having a stored procedure called when you need it is probably a capability already present in your environment. Hence all you need to do is put your desired code in the stored procedure. No need for you to hand craft the shceduling, initiation and management. One quite significant advantage of this approach is that you end up using a tehcnique that other folks in your environment already understand.
Writing the kind of code you're considering is very intersting and great fun, but in commercial environments is often a waste of effort.
Make another jar for your other Main class and within your main application call the jar using the Runtime.getRuntime().exec() method which should run an external program (another JVM) running your other Main class.
The way you start subprocesses in Java is Runtime.exec() (or its more convenient wrapper, ProcessBuilder). If that doesn't work, you're SOL unless you can use native code to implement equivalent functionality (ask another question here to learn how to start subprocesses at the C++ level) but that would be at least as error-prone as using the standard methods.
I'd be startled if an application server like Oracle allowed you access to either the functionality of starting subprocesses or of loading native code; both can cause tremendous mischief so untrusted code is barred from them. Looking over your edit, your best approach is going to be to rethink how you tackle your real problem, e.g., by using NIO to manage the sockets in a more efficient fashion (and try to not create extra files on disk; you'll just have to put in extra elaborate code to clean them up…)

Categories