How to set properties on a Tomcat application specific? - java

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

Related

How to pass individual command line arguments for multiple web application instances on a tomcat server

We have a tomcat server up and running.
We want our application to run as 5 independent instances on this tomcat server.
Each instance needs a different set of command line arguments to run properly.
How can we pass those arguments per instance?
We run the current version of tomcat server.
We have a Spring-Boot-Application which needs to run as 5 instances on this tomcat server. This is so that each instance takes care of a single port and on the business-level serves a different environment (dev, test, ...).
We are using different spring profiles per environment and therefore need to pass those to each instance running on tomcat.
Thing is: We cannot figure out how to pass those arguments.
There seems like no configuration to do this per instance.
We know about the JAVA_OPTS which are used on the entire tomcat.
We thought about declaring those arguments envrionment variables, but:
- potential other applications shouldn't know about those configurations.
- the configuration is pretty specific per instance and therefore a lot of 'noise' is produced which might be hard to maintain in the future.
As we look for the right place and right way to do that, there is no code yet.
Expected result:
5 instances of the same application are up and running on a tomcat server, each configured individually.
Hoped for:
A way to alter the config.xmls or alter a batch script to pass command line args.
You can't give parameters when deploying a war, so that's out of the question.
You'll have to do 5 builds, but then you can set the profiles to be used in application.properties. Shouldn't be too hard to automate, and technically you only need to build once, if you then make copies of the war and replace the property file.
Update:
What we finally came up to:
We have an individual context.xml for each instance and each environment. The differenct context.xmls are managed in a repository.
During deployment the respective context.xml is copied next to the war-file.
We are pretty happy with this solution, as we were able to automate the entire process and even have a context repository in place.

setting java tmp directory for a specific application deployed on websphere

I'm faced with a problem related to changing the java.io.tmp for just one application (called app1) by doing this : System.setProperty("java.io.tmpdir",'specific path'); .
Unfortunately, during performing tests, it was revealed tha the java.io.tmp has been changed for all application deployed on the websphere application server 8.0.
Is there any solution to fix that? I would really appreciate any help.
NB : the app1 is using JRC ( java runtime component) of crystal report and it generate huge tmp files under /tmp. that's why i want to change the java io tmp.
System properties are global to the JVM, so you cannot define a system property to apply to a single application on an application server - anything defined in a system property will apply to all apps and even the server runtime itself. There's no way to limit a system property definition to just an application scope.
The best solution is probably going to be seeing if the tool you're using is configurable to use some other definition for its temp location; if not, you will probably have to take it up with the provider or see if there's a way to add your own extension.

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 does CATALINA_OPTS works in Tomcat?

I am curious how does CATALINA_OPTS work in the background in Apache Tomcat? yes I know it executes on start and run of Tomcat and I add some parameters to be used by my program in it, And even I use it for long time add it to my VM parameters but not sure how it operates really.
For example isn't that possible to set those parameters say in Web.xml as context init parameters?
They're just command-line options that the Tomcat startup scripts pass to the Java runtime executable when it starts. You can't change them at runtime since the server is already running.
Extending Zutty's answser a bit. A running instances of Tomcat could be tweaked with JMX. .

Executing a class in remote jvm

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.

Categories

Resources