How does CATALINA_OPTS works in Tomcat? - java

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. .

Related

How can i set a global variable for Java so that it puts all java applets through a proxy?

I am trying to figure out how to make it so all java applications running on the machine are put through a provided proxy. I am doing this because the application that will be running does not support proxies by default and due to the circumstance i can not just give it command arguments. Below is what I have found so far and I have triied both the _JAVA_OPTIONS, JAVA_TOOL_OPTIONS, and _JPI_VM_OPTIONS. The application I am trying to work with is minecraft.
Prior to this issue I couldnt determine why my proxy application that I have built in C# using Titanium Web Proxy was not picking up on the minecraft traffic, and I have come to the conclusion that it is because it is not using the system's proxy. Here are the commands I have used to try setting the variable that are still not causing the JVM to go through the proxy.
set _JAVA_OPTIONS=-Djava.net.useSystemProxies=true
set _JPI_VM_OPTIONS=-Djava.net.useSystemProxies=true
set JAVA_TOOL_OPTIONS=-Djava.net.useSystemProxies=true
Guess my question is , is this possible?
If you find yourself using the same options over and over before laucing a java process, you can set up a special environment variable to contain your default options and the JVM will pick up the the values.
If the Java process is launch via java.exe then the environment variable is called _JAVA_OPTIONS (see JAVA_TOOL_OPTIONS below for a better option),
e.g. In Windows:
set _JAVA_OPTIONS=-Xms64m -Xmx128m -Dawt.useSystemAAFontSettings=lcd
In Linux:
export _JAVA_OPTIONS='-Xms64m -Xmx128m -Dawt.useSystemAAFontSettings=lcd'
ref : https://docs.oracle.com/javase/8/docs/technotes/guides/2d/flags.html
If the Java process is launch via javaw.exe (Applet) then the environment variable is called
_JPI_VM_OPTIONS.
For example :
_JPI_VM_OPTIONS = -Dsome.property=true
For a Java Web Start process (javaws.exe), the environment variable is called JAVAWS_VM_ARGS.
For example :
JAVAWS_VM_ARGS = -Dsome.property=true
But .. The preferred way is to use an environment called JAVA_TOOL_OPTIONS.
_JAVA_OPTIONS environment variable was ok but was not documented or supported. Since it is not >standardized, other vendors have their own names e.g. IBM_JAVA_OPTIONS. Leading underscore names are >private by convention so it's not a good to standardize the usage of _JAVA_OPTIONS. That's why >JAVA_TOOL_OPTIONS should be the preferred choice.
Maybe this question on the Arqade (another StackExchange site) can help: How can I play Minecraft through a proxy server?;
or, among others on StackOverflow, How do I set the proxy to be used by the JVM
Basically setting JAVA_TOOL_OPTIONS to include -Dhttp.proxyHost=proxyURL -Dhttp.proxyPort=proxyPORT -Dhttps.proxyHost=proxyURL -Dhttps.proxyPort=proxyPORT
(java.net.useSystemProxies should also work... but maybe minecraft (starter) is not respecting these settings - I believe you can set options in the starter as well)

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.

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

How to start Tomcat with a specific server.xml under Windows?

I want to start Tomcat 6 with special configuration sometimes, not using the "server.xml". So I created another xml file named server_test.xml. Now I want to tell tomcat to use this configuration. How is this done?
I found nearly nothing searching the web. Only that:
"Use different server.xml file in Tomcat configuration: ./tomcat.sh start -f /var/tmp/server-${USER}.xml"
This is exactly what I want. Maybe this is working for linux systems but not for windows. Any ideas out there?
I've got it. I took me the half night, but it works :)
At first I also thought of symbolic links, but under Windows it's not a thing you would like to use. My second thought was modifying catalina.bat, but that's not that easy. And different CATALINA_HOME's is not what I really want.
So what have I done? I've provided the server.xml as a parameter to catalina.bat.
catalina.bat start -config \conf\server_test.xml
Nice and easy :)
You can have a lot of server configuration files and provide the one you need to the start and stop script. The tricky thing was that the Catalina class gives you the wrong usage information :
usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { start | stop }
But if you exchange the parameters and first provide "start" or "stop" and then the "-config ..." argument, everything works.
Also very nice is that you can use this solution the create different run configuration in IntelliJ IDEA. I have one where the Tomcat connects to a local database and one connecting to a development database. For each I have a different server.xml.
I hope this helps.
Regards,
Sebastian
It doesn't look like there is a (documented) option you can pass to startup.sh or catalina.sh to change this.
Perhaps you can set server.xml as a symlink to the file you actually want to use, and just change the symlink prior to starting the server when you want to change it?
Otherwise you can play around with using different values of $CATALINA_HOME but this would require you to duplicate the entire directory structures.
tomcat.sh hasn't existed since 3.x and, to be honest, I don't recall it having '-f' option back then either.
You have two choices here:
A) You can setup multiple tomcat instances as described here and switch between them by pointing CATALINA_BASE to the one you want.
B) You can create multiple server.xml files named differently (e.g. server-1.xml, server-2.xml, etc...) and write a simple batch script that would copy the one you specify as command line argument to the actual server.xml and then start Tomcat.

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