General considerations

This section describes how to inject jProxyLoader into nearly any java application to allow passing connection from existing application through defined proxies. If you are looking for a way to develop against jProxyLoader please refer to "Developing against jProxyLoader" page.

JProxyLoader installs itself in java application by passing special parameter to java/jvm which loads JProxyLoader as a ClassLoader for the application. This special ClassLoader when is instantiated by jvm installs custom proxy selector which later is used by jvm to determine which proxy should be selected for particular connection.

Installing jProxyLoader to existing app

To install jProxyLoader as a ClassLoader firstly add jproxyloader.jar to your application classpath, secondly add following parameter to application startup command line parameters:

-Djava.system.class.loader=net.sf.jproxyloader.JProxyLoader 

If you get startup error: java.lang.ClassNotFoundException: net.sf.jproxyloader.JProxyLoader refer to Troubleshooting section.

If custom proxy selector was installed correctly you should see following message in console:

jProxyLoader: Initializing proxy jProxySelector with no proxy hosts: [], custom dns servers: [] and custom proxies config: []

If your application already trys to open socket to any url you should also see in log (right before opening first connection):

jProxyLoader: Unable to load properties from classpath resource: classpath:/jproxyloader.properties
jProxyLoader: Reinitialized jProxySelector with no proxy hosts: [], custom dns servers: [] and custom proxies config: []

Second message is displayed only when application trys to open first connection. In case you are sure that application opens connection to any url but you don't get the message "Reinitialized jProxySelector ..." it might mean that application overridden jProxyLoader - see Limitations on index site for details.

As can be observed above jProxyLoader is initialized twice (you can see two messages mentioned above). This is because of special way of loading configuration files from classpath resources. In general there are two stages of jProxyLoader initialization. Early stage takes place on application startup. At this point two kind of configurations are read: configuration basing on java parameters and configuration read from defined file on disk. Late stage takes place right before first connection is made. At this point following configurations are read: default configuration from jproxyloader.properties file placed on classpath, configuration read from custom file on classpath. After late initialization stage is completed configuration discovered in early stage is merged with configuration defined in late stage, thus forming configuration "combined from many sources".

Understanding configuration options

Configuration of jProxyLoader can be loaded from following sources:

  • system properties (every option is passed as a separate parameter to java/jvm)
  • file dropped at any location on local filesystem
  • default configuration file on classpath - jproxyloader.properties
  • custom configuration file on classpath

As stated above configuration from all these sources is merged into one configuration. Therefore you can define one proxy as a system property, another in jproxyloader.properties file etc. Also you can define proxies in one of configuration sources and hosts which should use those proxies can come from another source.

Three configuration types basing on files have exactly the same format. Let's have a look at an example of valid configuration:

proxydef.localhttp.hostname=192.168.1.200
proxydef.localhttp.port=6070
proxydef.localhttp.type=http
proxydef.localhttp.proxified.hosts=google.com

proxydef.kangaroo.hostname=kangaroo.mydomain.com
proxydef.kangaroo.port=7070
proxydef.kangaroo.type=socks
proxydef.kangaroo.proxified.hosts=myhost1.dmz|173.194.70.136|sourceforge.net|www.sourceforge.net

noProxyHosts=yahoo.com|localhost
customDnsServers=10.0.1.18

As you see there are four types of entries in the file. First eight lines contains definition of two proxy servers. Each proxy server definition consists of four lines. Each line starts with "proxydef" keyword followed by dot, followed by alphanumeric name of the proxy (this is your custom name), followed by dot, followed by one of the keywords:

  • hostname - this is the either IP address of the proxy or domain address of the proxy (fdqn)
  • port - the port on which the proxy is listening for connections
  • type - type of the proxy - can by either http or socks - should reflect actual type of the proxy
  • proxified.hosts - defines a list of hostnames or IPs which should be handled by this proxy. Hostnames should be separated with pipe character ("|"). Note: sourceforge.net and www.sourceforge.net are considered separate hostnames so if you want connections to both hosts (with and without "www." prefix) to go through proxy you need to define this explicitly (you need to put both hostnames in proxified.hosts property).

Now suppose we would like to instruct jproxyloader to load above configuration. For this let's assume we saved the file (with the content from above example) on local filesystem in directory C:/proxydef/myproxies.properties. To load this file we need to add an extra parameter to java application:

-DjplConfigFile=C:/proxydef/myproxies.properties

Whole command line, which injects jproxyloader to your application and reads configuration from above file is presented below. The parametr -cp jproxyloader.jar puts jproxyloader.jar on classpath (this of course can be done another way for example by adding jproxyloader.jar to CLASSPATH system variable).

java -cp jproxyloader.jar 
 -Djava.system.class.loader=net.sf.jproxyloader.JProxyLoader 
 -DjplConfigFile=C:/proxydef/myproxies.properties MyApplication

In the example above there are two proxy servers defined. One with name localhttp defines a http proxy, listening on host with ip 192.168.1.200 on port 6070. Any connection made fo google.com host will be directed to go through this proxy. Second proxy is a socks proxy listening on host kangaroo.mydomain.com on port 7070. This proxy will receive any connections made by application to hosts: myhost1.dmz, sourceforge.net and www.sourceforge.net and to IP address 173.194.70.136. Note: although the ip 173.194.70.136 belongs to youtube.com it does not mean that connection made to youtube.com in your application will go through kangaroo.mydomain.com proxy. It means that if application opens connection to ip 173.194.70.136 than it will go through kangaroo.mydomain.com proxy. If your application sometimes uses ip address 173.194.70.136 to connect to youtube.com and another time it uses hostname youtube.com for opening the connection, you need to put both the ip (173.194.70.136) and hostname (youtube.com) in proxified.hosts property.

The next line in the example starting with text "noProxyHosts" defines for which hosts direct connection should be used. It efficiently overrides the default proxies which might have been configured by passing native java parameters to your application. As you might consider this is useful only for some rare cases. To demonstrate the benefit of this params in such "rare case" let's consider two applications which are normally started using java native proxy params:

application 1:
java -Dhttp.proxyHost=myproxy.com -Dhttp.proxyPort=8080 -Dhttp.nonProxyHosts=yahoo.com MyApplication1

application 2:
java -DsocksProxyHost=mysocks.com MyApplication1

Application1 uses http proxy myproxy.com for every connection. However it needs direct (no proxy) connections to yahoo.com. Therefore it defines standard java jvm parameter http.nonProxyHosts. Application2 would like every connection to go via mysocks.com. Now if Application2 would like direct (no proxy) connections to yahoo.com (keeping every other connection to go via mysocks.com) it would run into trouble because there is no such parameter like "nonSocksProxyHosts" for socks proxies in java. Here jProxyLoader can give a hand, allowing to set noProxyHosts parameter for socks proxy. First you need to create a config file for jProxyLoader and drop it on local filesystem (let's say that the file is in following location: "C:/proxyconf/jpl.properties"). Then you put following content to this file:

noProxyHosts=yahoo.com

Now you can run application with help of jProxyLoader like this:

application 2:
java -cp jproxyloader.jar 
 -Djava.system.class.loader=net.sf.jproxyloader.JProxyLoader 
 -DsocksProxyHost=mysocks.com 
 -DjplConfigFile=C:/proxyconf/jpl.properties MyApplication1

After running above command in application console you should see message saying that jProxyLoader will force direct connection for host yahoo.com. All the other connections will go as usual (so via socks proxy mysocks.com).

jProxyLoader: Initializing proxy jProxySelector with no proxy hosts: [yahoo.com], custom dns servers: [] and custom proxies config: []

More about how proxy precendence works when using jProxyLoader you can read on Proxy precedence page.

Note: in above example there is no need to create config file at all. In this case you could set up "no proxy hosts" by "system properties configuration" i.e. by adding extra jvm param "-DjplNoProxyHosts=yahoo.com". More about this you can read below where system properties configuraton is explained.

Last line in config file starting with keyword customDnsServers allows to define extra DNS servers which should be used by java to resolve domain names to ip addresses. You define DNS servers by giving ip addresses of dns servers (not: domain names, but ip addresses) separated by pipe character ("|"). Using this setting is only needed in case application is trying to resolve dns name which is only known behind the proxy. In the first example we see that myhost1.dmz should go via "kangaroo" socks proxy. However application may try to resolve myhost1.dmz to ip address before actually opening connection to the host, so before jProxyLoader has chance to forward the connection. To overcome this problem you need to allow jvm to resolve this domain name by setting custom dns servers. These servers will be examined by jvm in first place and if they fail to resolve domain name, local dns will be used. This problem is also exaplained on Troubleshooting page. NOTE: on jre prior to version 7 local dns might not be used in second place. This is due to internal way how jvm resolves dns names. In this case you can enter local dns ip address to "customDnsServers" configuration variable of jProxyLoader or even better just launch your application on java7.

Configuration sources

As stated above configuration can be read from many sources: system properties, file on local filesystem, default configuration file on classpath (jproxyloader.properties), custom configuration file on classpath.

Last three options reads configuration from file. The format of the file is common for all configuration types basing on files. The only difference is the location were from the file is loaded. In the main example described above you saw how to load a file from local file system. You do this by adding java/jvm parameter "-DjplConfigFile":

-DjplConfigFile=/path/to/my/configfile.properties

You can also use prefix "file:" for readability reasons:

-DjplConfigFile=file:/path/to/my/configfile.properties

In similar way you define your custom configuration file which is placed on classpath. The only difference is that you use "classpath:" prefix.

-DjplConfigFile=classpath:/myconfigfile.properties

JProxyLoader also trys to load configuration from default configuration file "jproxyloader.properties", so if you drop jproxyloader.properties file to your classpath it will be discovered automatically.

IMPORTANT: files on classpath (both default and custom configuration file) will not be parsed until first connection is made by java application. This is called "late initialization" in jProxyLoader, so if you want to test whether configuration is read correctly from classpath you need to have application which actually opens the connection. See "Installing jProxyLoader to existing app" on the top of the page and "Command line app" example.

To illustrate this you can put jproxyloader.properties in "some_dir" directory and add this directory to classpath (this will result in loading jproxyloader.properties automatically from classpath):

java -cp "jproxyloader-1.0-RC1.jar;some_dir/" -Djava.system.class.loader=net.sf.jproxyloader.JProxyLoader MyApp

// on application startup following log will be written:
jProxyLoader: Initializing proxy jProxySelector with no proxy hosts: [], custom dns servers: [] and custom proxies config: []

// on first connection attempt following log will be written:
jProxyLoader: Reinitialized jProxySelector with no proxy hosts: [www.host1.com, myhost2.com], custom dns servers: [] and
 custom proxies config: [[http@192.168.1.148:8090#[another.proxified.host1, myproxifiedhost1]], [socks@mysocks.test:6070]]

Last configuration option is configuration by system properties. This type of configuration is similar to file based configuration because you set the same options but you do this by passing extra command line parameters. To define a proxy via system properties you need to create four system properties like below:

-DjplProxyDef.localhttp.hostname=192.168.1.200 
-DjplProxyDef.localhttp.port=6070
-DjplProxyDef.localhttp.type=http 
-DjplProxyDef.localhttp.proxifiedHosts=google.com|anotherhost.com|10.100.115.116

Each property starts wigh jplProxyDef keyword, followed by dot, followed by any alphanumeric name of the proxy, followed by dot, followed by one of the keyword: hostname, port, type, proxifiedHosts. All works the same as for config file i.e. hostname defines either ip or domain name of the proxy host, port defines port of the proxy, type defines type of the proxy (socks or http) and finally proxifiedHosts defines list of hosts which should be handled by this proxy (hosts should be separated with pipe character ("|")).

To define "no proxy hosts" you set up "-DjplNoProxyHosts" parameter, where you provide list of hosts for which direct connection should be used separated with pipe character:

-DjplNoProxyHosts=somehost.com|10.10.100.13

To define custom dns server you set up "-DjplDnsServers" parameter, where you provide list of ip addresses of extra dns servers separated by pipe character.

-DjplDnsServers=10.0.1.18

Debugging and logging

It is possible to increase logging level to have more insight in what jProxyLoader is doing and how it reads configuration files. To do this pass "-DjplLoggingLevel=DEBUG" parameter to your java program. Possible values for -DjplLoggingLevel are: INFO, ERROR, DEBUG. Default logging level is INFO, ERROR prints only error messages, DEBUG provides a lot of helpful debugging messages. See also Troubleshooting page for common problems when using jProxyLoader and Limitations section on Introduction page.