Executing a class in remote jvm - java

I have a small test class that I want to run on a particular jvm that's already up and running (basically it's an web application running on Tomcat) . The reason I want to do this is I want to execute a small test class (with the main method and all) within that jvm so that I get the same environment (loaded and initialized classes) for my test class.
Is it possible to indicate that ,say through a jvm parameter, that it should not initialize a new vm to execute my class but instead go and execute on the remote vm and show me the result here, on my console. So the local jvm acts as a kind of thin proxy ?
I am not aware in case there are some tools that should make this possible .Also heard somewhere that java 6 jvm comes with an option like this , is that true ?
Please help me.
Thanks,

After reading this question and the answers, I decided to roll my own little utility: remoteJunit
It is lightweight and dynamically loads classes from the client to the server JVM. It uses HTTP for communication.

You might want to take a look at btrace. It allows you to run code in an already started JVM provided you don't change the state of the variables inside that JVM. With this kind of tracing, you might be able solve your problem in a different way. Not by running extra code in form of a new class but by adding safe code to and existing class running inside a JVM.
For instance, you might System.out.println the name of the file when there is a call to File.exists.

You might find JMX useful. Register an MBean in the server process. Invoke it with visualvm (or jconsole). (tutorial) Never tried it myself, mind.

RMI would also do the magic.
http://java.sun.com/javase/6/docs/technotes/guides/rmi/index.html
Make your web application start an RMI registry and register your service
beans there.
Then in other JVM you can run a program that queries the RMI registry
started by your web application for the services you want to verify
and you are done.

I assume "small test class" is basically some debugging code you want to run to monitor your real application, which is deployed remotely on a Tomcat. If this is the case, you should connect your Eclipse debugger remotely to the Tomcat instance, so you can set a breakpoint at interesting locations and then use the Display view of Eclipse to run any arbitrary code you might need to perform advanced debugging code. As java supports Hot Code Replacement using the debug mechanism, you can also change existing code on the remote side with new code at runtime.

Related

Java - control flow of application with environment variables

This is more of a general best practice question regarding environment variables and their uses in Java.
Let's say I have an web application (1) that uses web services to target another application (2). I want in pre-prod environments to keep this link as optional in the flow of the application: if application 2 is down, I want to target a mocked server, that always gives back an answer.
How do I do this the best way?
I was thinking I can use an environment variable like app1.usemockserver = false. When I know that app 2 is down, I can set app1.usemockserver = true, and with an IF in my code I can target the mock server, and not application 2.
Is it something wrong doing it this way? What alternatives could I use?
This one would be difficult using environment variable as JVM will pick up all environment variable that was defined when JVM was launched. Anything chnaging there after wont be picked up.
I would suggest you look at JMX and expose a bean which will set the boolean flag to switch from one environment to the other dynamically within existing JVM.
You could even expose RPC call to JVM to set/reset the boolean flag but i would prefer JMX.
Another way would be to have a load balancer service running on top of your service which will do hearbeat and once it doesn't hears from respective servcie, it switches over to the other.
Based on what SMA answered, I think the best choice would be in fact using JMX.
But, to have something fully automated, that falls back to a mocked web service, JMX could be used in conjuncture with a modified circuit-breaker, like in this framework:
Spring in Practice - kite
So, when the circuit-breaker opens, it could just target the mocked web service.

How to set properties on a Tomcat application specific?

I have a tomcat service with a single application, and set the following property in setenv.bat:
set JAVA_OPTS=%JAVA_OPTS% -Dspring.profiles.active=production
This uses spring-boot and ensures the application always runs in production profile mode.
Problem: I now want to drop a 2nd application in that should not run in production. How could I configure the java opts application specific?
Is that possible at all? Or would I have to create a 2nd tomcat instance?
The JAVA_OPTS variable is used by Java in the creation of the Java virtual Machine (the real process) so you can't told Java to create in one process 2 different processes.
I think the only solution will be to duplicate the web server (quite easy with most of them) and (having care of the ports !biggest problem!) running a second JVM for developing.
hope it helps

What does this method do checkCreateClassLoader in the security manager class

I would like to know what the checkCreateClassLoader method does , its not very clear in the java api doc.Yes , let say I have an application and want to avoid someone dumping my classes during run time(using java agent or reflection). Can I use this method for avoiding this . Thanks
MalikDz
Let say I have an application and want to avoid someone dumping my classes during run time(using java agent or reflection). Can I use this method for avoiding this?
No.
First of all "Java Agent" already implies complete control over the runtime environment.
If you have a user running your code on their own machine, they can get at your class files.
If the code is running on your machine (but the user can somehow upload his own JAR files), then you can use a custom Security Manager, maybe in combination with a custom ClassLoader, to disable reflection and probably also access to the bytecode of classes (and also restrict communication channels that would be required to send this "leaked" data back to the user).

Can you use multiple proxies at once in java?

I'm coding my server in java, and through the day, my server has to connect through 5 different proxies at once to other servers and gather data. However, reading about java proxy settings through stackexchange, I see that when you set a proxy, its effect is VM-wide, meaning whatever network activity that .jar was doing, it will do it through a proxy if somewhere a different thread sets a proxy setting within the jar.
I'm currently using this method of setting a proxy, which according to some tests it's actually pretty functional and works fast.
System.getProperties().put( "http.proxyHost", host );
System.getProperties().put( "http.proxyPort", port );
However, I can't really afford having 5 jars doing the same thing with different proxies, I tried it to, it would be a simple solution however I can't afford to use that much ram only for this, as my server is huge.
You need to call each connection with its own proxy settings. The Answer here by NickDk defines how you can call a url with its own proxy settings. You will need to do the same with each of your 5 proxies separately.
here is described the use a library embeded in the JRE, able to handle "proxypac" files in wich any combination of proxies can be defined.
since it is embeded in the JRE, standard ways to configure a Java application with a proxypac file (standard launch optional parameters) might exist, but I am not aware of it.
Howhever the solution described in the link provided should fit your needs since your usage is programatic.

How to restart a java program from within java?

I have a java program that is quite large and we want to make it so the user can quit the app and login as another user. To do this we would like to shut down the app and restart it so it presents the login dialog to the user. The problem is that the application is quite large and is poorly written. It has a lot of static variables that hold some sort of state info. Ideally I would like to rewrite the app to handle a situation where these can all be cleared out, but in reality we need to provide this functionality asap.
What I was thinking would be the easiest would be to simply stop the app and start a new vm. However, it seems surprisingly difficult to stop and application and start the same app while shutting down the current one. Does anyone have experience doing this?
EDIT: we are pursuing using Runtime.exec to call the same app again, but exec() wants to block so we have to jump through hoops to get it to work on every platform (Windows, Mac, Linux). I would prefer a platform independent way of doing it.
If you can modify the code, maybe you can exit the program and use the Runtime class (java.lang.Runtime) to start the same program again (with the same arguments?) using the exec() method.
http://download.oracle.com/javase/6/docs/api/java/lang/Runtime.html
Edit: That is to say, you first run the new process, and then exit the program. The other way would of course be much more difficult or impossible(?). :)
If you truly want to stop the JVM and restart it, then you'll have to write some wrapper script (shell script or batch file, depending on your OS) that does it. You could use a special return code from System.exit() to indicate that the application should be restarted.
And that's probably the best way to do it. You could play some classloader tricks, in which your create a custom classloader that to load the application's classes. However, there are a lot of ways for this to go wrong: for example the application code might call System.exit() in some hidden place, or it might contain code that retains internal references in classes loaded by the bootstrap classloader.
Static members are associated with the classloader:classname. You can create your own classloader and instantiate your app via that. Then when you want to restart, throw away the classloader and create a new one. This is how app engines like JBoss are able to reload applications on the fly.
You can use Runtime or ProcessBuilder to relaunch your application but you probably have to modify your application a little bit as I'm pretty sure you don't have a way to retrieve the java executable full path from within the JVM.
I suggest you to implement a launcher (as an executable or a script) and use the java return code to know if you need to exit or if you need to exit or restart.

Categories

Resources