Unable to access JVM custom property in Java - java

I'm creating a custom property in my WebSphere Application Server (ND 8.5.0.2) at below path as prescribed by plenty of articles on web:
Application servers > SamplesServer > Process definition > Java Virtual Machine > Custom properties
As per the articles, I can access this custom property using
System.getProperty("PropertyName");
However, it always returns NULL. I tried all the possible ways and done plenty of Googling but yet to retrieve this property.

Also, you can specify system properties in the "Generic JVM Arguments" field of the Java Virtual Machine configuration mentioned in your question. Here's a technote with the procedure: http://www-01.ibm.com/support/docview.wss?uid=swg21417365. Add each property in the form -DpName=pValue. For example: -Dcom.ibm.ws.example=true
If you are using a Deployment Manager to configure these settings, please ensure that you synchronize the configuration after saving the settings.

If you run:
$ jcmd <pid> VM.system_properties
from the host your server is running on, it will print out all system properties identified by that JVM. If you don't know what the pid is, then you can run:
$ jps
and it will show you a list of all processes along with their ids that you can use to connect to to find this information.
That will tell you whether the problem is in the way that you're setting the property, or in your code. However, from the above the code looks correct, which suggests that the custom property isn't being set in the way you are launching the process.

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

JDK7u21 RMI changes

The Release Notes of JDK7u21 specified the changes related to RMI:
From this release, the RMI property java.rmi.server.useCodebaseOnly is
set to true by default. In previous releases the default value was
false.
This change of default value may cause RMI-based applications to break
unexpectedly. The typical symptom is a stack trace that contains a
java.rmi.UnmarshalException containing a nested
java.lang.ClassNotFoundException.
If these exceptions occur, the preferred way to solve the problem is
to configure all RMI clients and servers to use the same codebase, by
specifying proper values in the java.rmi.server.codebase system
property. This is typically done by adding the -D option to the
command that starts up the application: java
-Djava.rmi.server.codebase=file:////(path-to-remote-classes)/
It also specified in the documentation here that workaround is to set the java.rmi.server.useCodebaseOnly property back to false.
However, even when I explicitly set this property to false, I am getting an exception mentioned above. Any clue here please?
And if I have to solve it by the preferred way described above (by setting the -Djava.rmi.server.codebase=file:////(path-to-remote-classes)/, then which path should I set over here? My workspace/bin?
You have to make sure to set the properties on all JVMs that are using your remote classes. This includes your RMI server, the RMI clients, and the RMI registry. If they are all on the same machine, then you can set java.rmi.server.codebase on them all to a file: URL that points to the location of the classes. If they're not on the same machine, then you could make the classes available using an HTTP server, and then set the codebase property of the remote JVMs (presumably the clients) to use an http: URL that points to where the classes are available. Or you could make the classes available to remote JVMs through some other means, such as copying them, or using a shared filesystem, and then set the codebase property to a file: URL.
Your attempt to apply the workaround of setting java.rmi.server.useCodebaseOnly to false might not be working for a couple reasons: you might not have set it in all of the interacting JVMs, or you might not have set the codebase property to the right value.
Since you're having to go to the trouble of configuring the registry and all the clients, you might as well pursue setting their codebase property to the right URL, instead of pursuing the workaround of setting useCodebaseOnly to false.
You would need to either:
Set it to false at all the JVM(s) which download classes, and ensure that java.rmi.server.codebase is set to something useable at all the JVMs which send objects whose classes may need downloading, or
Leave it alone but make sure that every JVM in the system is started with a java.rmi.server.codebase property that points to a useable codebase for that JVM.
It's a very strange change to make. I don't see any security implications, just a nuisance change that changes semantics at all the codebase recipients. With useCodebaseOnly=true, you have to set java.rmi.server.codebase at the receiving JVMs, where otherwise you only have to set it at the sending JVMs. This isn't clear from the documentation.
I am sorry, I solved it on my own. The problem was wrong number of parameters were being passed to my .ksh file. This caused the problem starting RMI registry.

JVM and OS DNS Caching

I am facing a problem with JVM and DNS.
Everything I'm reading (including the docs and this) says that I can disable JVM DNS caching using networkaddress.cache.ttl, which can be set using java.security.Security.setProperties, but through the standard approach of using system properties. I have successfully changed this to 0, so no more caching in my JVM.
But now, on each call of InetAddress.getByName("mytest.com"), it seems that my JVM is using the system DNS cache (in my case Windows 8). Indeed, between 2 calls of the method, I have changed the BIND9 properties for "mytest.com", but the IP return is still the same. Here is the workflow:
setCachePolicyInJVM(0) in my Java code.
set mytest.com to 192.168.1.188 in BIND9, restart.
InetAddress.getByName("mytest.com").getHostAddress(); -> 192.168.1.188
set mytest.com -> 192.168.1.160 in BIND9, restart.
InetAddress.getByName("mytest.com").getHostAddress(); -> 192.168.1.188 (should be 160 if there was no caching).
Flush the Windows DNS
InetAddress.getByName("mytest.com").getHostAddress(); -> 192.168.1.160
I have read several times that the JVM does not use the system cache, but that is wrong: it clearly does.
How do we force a new DNS resolution on each call, bypassing the OS DNS cache?
I think I've run into this problem, or a very similar one. What I did then was to implement my own DNS provider for the JVM, see how to change the java dns service provider for details. You can use the dnsjava mentioned there or roll your own.
You can either edit your $JAVA_HOME/jre/lib/security/java.security for Java 6-8 and $JAVA_HOME/conf/security/java.security property file to add the following property .
networkaddress.cache.ttl=1
It is not available to set it in command line.
Since these 2 properties are part of the security policy, they are not
set by either the -D option or the System.setProperty() API, instead
they are set as security properties.
To set this property inside the code, you can use the following method.
java.security.Security.setProperty("networkaddress.cache.ttl", "1")
Or add the following property in the java command line.
-Dnetworkaddress.cache.ttl=1
It is also important to note that values are effective only if the corresponding networkaddress.cache.* properties are not set.
See Java 8 Networking Properties, Java 9 Networking Properties and VeriSign DNS Caching in Java Virtual Machines for more details.
This answer also adds some details.
From here it seems you should set sun.net.inetaddr.ttl. This worked for me.
Example from link:
java -Dsun.net.inetaddr.ttl=1 test
Enter the hostname
rrr
Output isrrr/129.145.146.100
Enter the hostname
rrr
Output isrrr/129.147.146.100

Running one file on multiple servers

Right now my team deals with about 4-5 different servers and about 2-3 different DB servers and we're using environmental variables to decide which server we're on and what server configuration to use.
Is there a better way to do this as my team continues to expand? I've considered compiler flags / args, but it doesn't seem as robust.
From my perspective, in java, you have basically 3 ways to crack this cookie:
Environment variables
-D JVM parameters (which are System Properties)
properties files
You've already discovered Environment Variables and that is pretty much "the unix way" to get the effect you are after; different configuration to common binary that customizes the running application for the environment it is executing on.
System Properties are really the Java "moral equivalent" of Environment Variables. They come in via -D parameters on your application's command line like...
java -Dlogback.configurationFile=/opt/dm/logback.xml -cp app.jar org.rekdev.App
Explicit Properties file processing http://docs.oracle.com/javase/tutorial/essential/environment/properties.html in Java is a third variant which you often see coupled with -D to get something like default behavior which can be overridden at runtime from the command line. That is what is basically going on with the logback.xml configuration above, the JAR file has a logback.xml inside it that will be used unless a System Property called "logback.configurationFile" exists, at which point the App will load it instead.
As you try to figure out how to keep this all in sync and working correctly in a multi-server environment, consider the use of chef http://wiki.opscode.com/display/chef/Home to do the deployments and put each specific environment's customizations under chefs control. Put the chef "recipes" in version control and, voila, full on configuration management.
SHIP IT!
I can see two scenarios
You embed all the different properties within your package (can be a war, ear, jar, or on the file system /yourapp/etc/)
You embed only one property file and this one is created during build (with ant or maven)
Say your app is named foo
Solution 1
It has the advantage that your app can be put as-is on any of the supported servers (all that have a property file in your app package).
Your properties will be named foo.dev.properties, foo.test.properties, foo.prod.properties, foo.damien.properties, foo.bob.properties.
One other advantage is that every developer working has its own dev file that he can safely push on svn/git/whatever and be sure that other developer won't destroy his config.
At runtime the application can check the -D parameter or even retrieve the hostname dinamycally, in order to load the correct property file.
Solution 2
It has the advantage that your package is not polluted by unnecessary properties files.
You must configure a lot of ant tasks/maven target in order to build for specific environment. You will have in your source directory the properties files for the environments also, but only one will be shipped with your app. This one foo.properties will only have placeholders for values, and values will be inferred within it using foo.ENV.properties with the right ant task/maven target.
At my actual job and the previous one also, we did use the solution 1, I think it brings flexibility.
Some parameter (like database user/password) were fetched directly from environment variables on the Unix servers though (so that only the server admins knew the credentials).
You can safely mix the solutions, in order to get where you feel there is the more flexibility for you and your team.

Categories

Resources