Setting JVM Proxy Variables
This would not typically warrant a blog post. However, I just spent days resolving it, and I wish I had found the solution earlier. I’m putting this out there for you, just in case you’re being whipped around by this problem.
The JDK responds to several system environment variables to control how it works for proxies. Here are the main ones:
You need to set these so that the JRE libraries work properly for network connections, particularly library classes in the java.net package.
Setting System Properties
Set these properties in your JAVA_OPTS exported environment variable or on the command line with the -D option like this:
Watching for Trouble
And here’s the real reason I’m posting about this. I am working with the AWS Java SDK, deploying apps to EC2 instances. These are Linux instances, which are not a problem except in this situation.
Not only did I need to set a proxy host but also a set of non proxy hosts to correctly access EC2 Meta-Data. I set my http.nonProxyHosts like this:
java -Dhttp.nonProxyHosts=’localhost,*.compute.internal,169.254.169.254′ MyApp.jar
However, I consistently received runtime errors from the AWS Java SDK libraries telling me that the metadata service couldn’t be reached, HTTP 403 errors for miles and miles.
The problem: the http.nonProxyHosts string is in the wrong format!
Using the Correct Format
The correct format is to use an OR symbol (“|”) between those hosts instead of a comma (“,”). Additionally, a simple OR is not sufficient. The problem is that the “|” needs to be escaped on Linux systems. So the correct way to set the variable is like this:
java -Dhttp.nonProxyHosts=’localhost\|*.compute.internal\|169.254.169.254′ MyApp.jar
If your app refuses to connect with an external service and you’re diddling with proxies, check your proxy environment variables again:
- Use “|” instead of a comma between non-proxy hosts.
- Use “*” instead of just leaving subdomains empty. Use this (“*.compute.internal”), not this (“.compute.internal”)