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.
Related
I work in a framework where remote objects export themselves like this: UnicastRemoteObject.exportObject(this, port, csf, ssf);
That's just a given, can't change it. I am now trying to include the RMIIO lib to do remote iteration. RMIIO exports remote objects with UnicastRemoteObject.exportObject(Remote, int), which according to the Javadoc uses RMISocketFactory. By default, RMIIO sets the port to 0 (any port).
Now I absolutely need RMIIO to reuse the existing RMI port that is used by all other objects (it's the only one that's open in the firewall), and also respect my settings for the socket factories, because of SSL and compression etc. What's the best way to do that, apart from changing the 3rd-party code? I'm using Java 8.
I had hoped there were system properties that would allow me to control the socket factories from the outside, but there do not seem to be.
So now I think that I need to call RMISocketFactory.setSocketFactory(RMISocketFactory) programmatically. Is that correct? It sounds a bit hairy to me. And is it correct that when I do that, I don't need to worry about specifying a port for the lib, because RMI would automatically try and reuse it when my socket factories implement equals() and hashCode() appropriately?
Sebastian
I found a feature of the RMIIO library that indeed solves my problem: you can supply your own class to do the exporting of remote objects. That class can be specified through a system property. Thus, the underlying Java remote stream implementation is decoupled from the RPC framework over which it is called. Good design!
I am looking for a open-source solutions which allow hosting different properties for different applications and allow changes. On any change of properties it should notify or push the change to the application appropriately.
So, instead every application managing the properties in physical file and deploying physically; these properties can be pushed to a single system. User will have GUI to load and change the properties as per right. Should allow push as mentioned.
If you have already similar open source solutions in mind please advice.
Is this something that Puppet can manage for you?
I don't think what you've described (as nice as it would be) will be likely to exist in an app server. If a program is looking for a file, it's either going to load it with a FileReader (or similar), or it will use ClassLoader.getResourceAsStream(). It might be looking for data that is returned in properties, format, XML properties format, or even something completely different like RDF with which to configure itself. Also many programs read their config on start-up and then hold the values in memory, so you would still need to reboot them to get them to change.
To get something like this to work there would need to be a standard for configuration provisioning and live updates. Once that existed the webapp authors and server vendors would each need to add support for the standard.
If you are the one writing the programs to be managed however, then you can write your programs to request configuration from a service, and have a configuration push feature.... there may be packages out there that can speed up adding that to your code, but I get the impression you are looking to manage programs written by others.
Have you considered to use JMX? I think he could be a good starting point to implement your requirements.
MBeans's attributes can store your application's properties, the MBeanServer will allow you to make them available from remotting, JConsole offers you an GUI to update properties values.
You also can write within the MBean some code that notify the corrrespondig application when a user change any properties using the GUI.
I'd like to profile network overhead of my RMI-based application. For instance, I'd be interesting to know how many bytes a stub transferred over the network, or how many method calls were done through it. I can't find anything in the RMI API to hook into, though. Is this possible at all?
I am not particularly fond of RMI and found JSon-based, Thrift and even XML-RPC easier to work with. However, sometimes we don't have a choice.
There is a microbenchmark suite for RMI, as well as object serialization, in the "test" tree of the jdk7/jdk repository, see:
jdk/test/java/rmi/reliability/benchmark
The script:
jdk/test/java/rmi/reliability/scripts/create_benchmark_jars.ksh
shows how to create two JAR files which is used in the benchmarking. You can pass command-line parameters to each each instance for specific settings such repetitions per run, etc. (One instance of the jar will run as the client and the other as the server, which is also configured from a command line parameter.)
I haven't played much with this myself - usually trusting existing benchmarks, for example:
http://daniel.gredler.net/2008/01/07/java-remoting-protocol-benchmarks
...or using tools such as (I haven't looked much at the last two):
JMeter (http://jmeter.apache.org/), Soap-stone (http://soap-stone.sourceforge.net/) or
JVM-serialisers (https://github.com/eishay/jvm-serializers/wiki/)
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 ...
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.