Skip to main content

We deserve a better proxy support!

Posted by kohsuke on August 10, 2005 at 1:16 PM PDT

Nowadays many Java tools need to access HTTP resources. For example, Ant has a task, Maven needs to download jar files, javadoc needs to locate package-list from a remote site, JAX-WS's WsImport reads WSDL from a remote website, and JAXB's schema compiler does the same for schema files. The list could go on forever.

So first let's look at how these tools support proxies?

Ant
With Ant, you either do export ANT_OPTS="-Dhttp.proxy.port=8080 -Dhttp.proxy.host=webproxy.acme.com" or use the setproxy task. The latter is particularly bad, because proxy setting is by its nature different from one developer to another. But this task requires that you set proxies inside a build script, which is supposed to be shared by multiple people. So you typically end up defining a property in a file like build.properties and tell individuals to override them. The former is better, but it's not well advertised.

Maven

With Maven, you typically write ~/build.properties like this:
maven.proxy.host=webproxy.acme.com
maven.proxy.port=8080
javadoc

Javadoc is probably the worst of those tools I mentioned here, because it doesn't even attempt to support a proxy. So you'll either have to download package-list and use the -linkoffline option, or you'd run it as javadoc -J-Dhttp.proxy.port=8080 -J-Dhttp.proxy.host=webproxy.acme.com ... which isn't mentioned anywhere in the documentation.

WsImport / XJC

These tools have the -proxy option to let you configure the proxy info. Fortunately they take the similar syntax, where the only difference is that XJC accepts userid/password authentication, whereas (I believe) WsImport doesn't.

The problem here is that every tool invents its own way of configuring proxies. So whenever I bring my laptop between home (no proxy) and office (need proxy), I have to dilligently change the settings in so many places. First, you change the IE connection, then you change Firefox connection, then ~/build.properties. Am I done now? No, I still have to modify ~/.svn/servers!

It would be much better if the configuration location is consolidated, so that I can only change it once and be done with it.

So, that's why I'm going to talk about this feature I recently discovered in Java SE 5, where you can tell the VM to use the platform proxy configuration (meaning IE's connection setting in Windows, or Gnome's if you are on it.) To activate this, you need to put the following lines in the beginning of your tool:

try {
    System.setProperty("java.net.useSystemProxies","true");
} catch (SecurityException e) {
    ; // failing to set this property isn't fatal
}

This has to be done before your tool starts accessing URL class and so on, because this system property is checked only once at the start-up time.

This works even with pre-Java 5 JVMs. It just doesn't take any effect, which is a reasonable fallback behavior.

I've already finished changing XJC, so it now works without the explicit -proxy option, as long as your Internet Expolorer / Gnome is configured correctly. Now if only Maven, Ant, javadoc, and million other tools could do the same...

Related Topics >>

Comments

Hi,
Very good post, I found it useful for maven and ant wsdl work.
For wsimport tool that ships with JDK, here's my tip.

I see that it does not have the facility to put nonProxyHosts, so I went ahead and used Java class invocations.

Something like this

java -Dhttp.proxyHost=proxyServer -Dhttp.proxyPort=9000 -Dhttp.nonProxyHosts="localhost|other-maching-on-lan|*.intranet-domain" -classpath %JAVA_HOME%\lib\tools.jar com.sun.tools.internal.ws.WsImport -p com.ws.client.pkg http://my-internal-domain/endpoint?wsdl

This worked for me very well