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.
Related
I'm looking for a java argument (or perhaps some different method) to allow me to specify a file to be used by the JVM as the java.security file, rather than using the one found in the JDK (in the JRE lib).
To give you a little more context, I am working with a WebLogic server that was set up by someone else and is running two (or more) different JVMs off the same JDK. We have run into an issue now where the work I'm doing on one JVM requires a different java.security file than the one that is currently being used by the other JVM. I am hoping there will be a way for me to just point my JVM at a new java.security file without having to point it at an entirely new JDK (due to space constraints, we would like to avoid uploading a JDK specific to each JVM).
I realize that the server's set up is not ideal, but completely rearranging the existing set up is not viable and not something I am in a position to do. So, I am hoping someone might have a creative solution that would allow for multiple JVMs running off the same JDK but with different security configurations.
I have been trying to find solutions out there, but it seems my Google-Foo is not as strong as I had hoped. Here's to hoping one of you has the answer!
Many thanks.
EDIT
Sorry maybe my original post was not clear, but I am interested in specifying the java.security file, also often referred to as the Java master security properties file, not the java.policy file which is found in the same directory.
My Solution
I will post my solution here just for reference of others who might fall into a similar situation.
As I can't seem to find an argument to specify at start up, I have decided that I will have to forgo the java.security properties file. It is possible to set properties and providers (typically configured in the file) within code using the Security class (java.security.Security). So, at least in the interim, I plan to write a class that will go through setting up my JVM specific security configurations after startup (essentially overwriting the default configurations provided by the file for the other JVM). While the obvious downside of this solution is that is does not externalize security configurations of this JVM, the solution does provide me a way to set JVM specific properties and providers without affecting the configuration of other JVMs running off the same JDK.
I appreciate the time and consideration given by others. Thanks =)
Looking at the OpenJDK source, you cannot change the loading of the java.security file. However, that file has a property called security.overridePropertiesFile which, if set to true (as it is in my current, vanilla install), allows you to load an additional security properties file specified through the system property named java.security.properties. Note also, that the command line syntax follows a similar pattern to the policy file where = specifies additional configuration and == specifies a complete replacement configuration.
Maybe the accepted answer on this thread would help you out; basically it says that you need to specify your own policy file and the final invocation should look like:
java -Djava.security.manager -Djava.security.policy=/some/path/my.policy
You can just set the system property -Djava.security.properties=***** to specify the security property you want to load, but you must set the property security.overridePropertiesFile=true prior to use this approach.
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.
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
I'm looking for a java argument (or perhaps some different method) to allow me to specify a file to be used by the JVM as the java.security file, rather than using the one found in the JDK (in the JRE lib).
To give you a little more context, I am working with a WebLogic server that was set up by someone else and is running two (or more) different JVMs off the same JDK. We have run into an issue now where the work I'm doing on one JVM requires a different java.security file than the one that is currently being used by the other JVM. I am hoping there will be a way for me to just point my JVM at a new java.security file without having to point it at an entirely new JDK (due to space constraints, we would like to avoid uploading a JDK specific to each JVM).
I realize that the server's set up is not ideal, but completely rearranging the existing set up is not viable and not something I am in a position to do. So, I am hoping someone might have a creative solution that would allow for multiple JVMs running off the same JDK but with different security configurations.
I have been trying to find solutions out there, but it seems my Google-Foo is not as strong as I had hoped. Here's to hoping one of you has the answer!
Many thanks.
EDIT
Sorry maybe my original post was not clear, but I am interested in specifying the java.security file, also often referred to as the Java master security properties file, not the java.policy file which is found in the same directory.
My Solution
I will post my solution here just for reference of others who might fall into a similar situation.
As I can't seem to find an argument to specify at start up, I have decided that I will have to forgo the java.security properties file. It is possible to set properties and providers (typically configured in the file) within code using the Security class (java.security.Security). So, at least in the interim, I plan to write a class that will go through setting up my JVM specific security configurations after startup (essentially overwriting the default configurations provided by the file for the other JVM). While the obvious downside of this solution is that is does not externalize security configurations of this JVM, the solution does provide me a way to set JVM specific properties and providers without affecting the configuration of other JVMs running off the same JDK.
I appreciate the time and consideration given by others. Thanks =)
Looking at the OpenJDK source, you cannot change the loading of the java.security file. However, that file has a property called security.overridePropertiesFile which, if set to true (as it is in my current, vanilla install), allows you to load an additional security properties file specified through the system property named java.security.properties. Note also, that the command line syntax follows a similar pattern to the policy file where = specifies additional configuration and == specifies a complete replacement configuration.
Maybe the accepted answer on this thread would help you out; basically it says that you need to specify your own policy file and the final invocation should look like:
java -Djava.security.manager -Djava.security.policy=/some/path/my.policy
You can just set the system property -Djava.security.properties=***** to specify the security property you want to load, but you must set the property security.overridePropertiesFile=true prior to use this approach.
I have a question on using System Properties in Java. Some classes like Authenticator require that we set the system properties regarding Proxy settings and than verify whether the Proxy was valid or not.
My question is should I remove the Set Properties after I am done using it ?
There are other parts of programs that might be using these Properties, this change will autmatically impact thier functionality.
Is there a way, I can set Properties local to a Function (some wrapper class)?
What are the good practises for setting system properties and using them ?
Things that use System.properties should have properties that have a global meaning to the running JVM, so that if, for example, you set a proxy, it should be the relevant proxy across that process.
So therefore there is no need to set them back. In fact, setting them back might make some APIs confused, as they may assume they get back the relevant value at all times, and didn't just cache it when they read it.
Of course if a given API isn't using them that way, then you might have issues, but that would really be an issue with a given API, more than a good practice issue with System properties.
In general, due to threading and synchronization issues, it is probably a good practice to set System properties only at the beginning of the JVM startup (either on the command line or in the main thread before starting other threads) with the expectation that the values remain unchanged for the remainder of the time running the JVM.
This doesn't answer your question about system properties in general, but regarding your specific problem with proxy settings properties, perhaps you can use a ProxySelector to isolate the Test Proxy you mention in the comments here?
You could create a subclass of ProxySelector that you utilize for the test. Make it such that it only applies the test settings when the test URI is attempted. This would isolate it from other requests.
This sort of global proxy setting inflexibility is what initially drove me to use HttpClient for HTTP needs instead of Sun's API.
Edit:
I'm not sure how I ever missed this method, but it is possible to get a URL connection and supply the proxy settings to that connection alone via java.net.Url.openConnection(Proxy)
.
If there is a chance that some other part of your program (or some other webapp in the container, etc) might be affected by "temporary" settings then it is a good idea to remove them.
Best practice would be to try an find some other way to do what you are trying to do. For example, consider creating your own protocol class that overrides a standard one in the area where it figures out what proxy to use.
If you cannot do that, try to structure your code so that the sequence:
change the properties,
do the operation,
restore the properties,
is done in a mutex that respected by anything that might be affected by the properties you are changing. This may be a hard ask though ...