duffymo
duffymo

Reputation: 308938

HTTP Proxy Setup For Java JVM

Setting up an HTTP proxy for Java JVM 6.x isn't working for me; I'm hoping someone can spot what I'm missing.

I have a Java application deployed on JBOSS 5.1.2 that makes several calls to external web services. I'd like to be able to intercept these calls using a proxy: Fiddler version 4.4.8.0.

After doing an SO search I added the following flags to my JBOSS VM parameters at startup:

-DproxySet=true -Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8888

I'm running JBOSS in IntelliJ 14.

I can see traffic from the browser to the application if I start JBOSS, Fiddler, and open the UI in Chrome. I do not see any calls from JBOSS to external services being intercepted. I thought I would see all the calls from JBOSS to external services in addition to those from the browser to JBOSS.

Update:

I tried adding these to properties-service.xml per this SO answer - no joy.

I'm running Spring 3, using Apache HttpClient as my web service client. I'm going to look into configuring proxy just for it.

Upvotes: 0

Views: 6579

Answers (2)

duffymo
duffymo

Reputation: 308938

Thanks to bmargulies and anyone else who looked at this. I have a solution that I hope will help someone else.

Adding -Dhttp.proxyHost parameters to my JVM startup options did nothing.

Adding those same parameters to JBOSS 5.1.2 configuration in my deployment properties-services.xml did nothing.

I believe that using Spring 3.x is a factor in explaining this behavior. I had to tell the Spring web service clients to use a proxy.

I added some Spring beans to wire in a Fiddler proxy HttpClient and injected that into the web service client, replacing the non-proxied version.

It failed the first time I tried it. It took me a while to figure out that the Apache Commons HttpConfiguration class didn’t follow the Java bean standard, so Spring blew up when it tried to wire it. I had to use the Spring MethodInvokingFactoryBean to get around it.

Here's the pertinent Spring configuration XML:

<!-- New beans for Fiddler proxy -->
<bean id="fiddlerProxyHost" class="org.apache.commons.httpclient.ProxyHost">
    <constructor-arg name="hostname" value="localhost"/>
    <constructor-arg name="port" value="8888"/>
</bean>

<bean id="fiddlerProxyHostConfiguration" class="org.apache.commons.httpclient.HostConfiguration"/>

<bean id="fiddlerProxyHostSetter" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="fiddlerProxyHostConfiguration"/>
    <property name="targetMethod" value="setProxyHost"/>
    <property name="arguments" ref="fiddlerProxyHost"/>
</bean>

<bean id="fiddlerProxyClient" class="org.apache.commons.httpclient.HttpClient">
    <property name="hostConfiguration" ref="fiddlerProxyHostConfiguration"/>
</bean>

Now I can see the calls from the application to the web service in Fiddler. Joy!

Upvotes: 3

bmargulies
bmargulies

Reputation: 100133

Those parameters, first and foremost, are read by HttpURLConnection. They are specific to HTTP, of course, and so any other means of connecting to the outside world will necessarily ignore them.

There are many good reasons for code to avoid HttpURLConnection and just open a TCP connection through a plain old socket, even if that code plans to talk HTTP. HttpURLConnection has several 'browser emulation features' that get in the way. For example, it's broken for CORS and rejects some legitimate HTTP verbs.

Code that does that and in turn happens to do HTTP might choose to respect those parameters, and it might not. For example, I'm reasonably sure that the Apache Commons HTTP library gives the caller a choice.

If you put JBoss in a debugger and break on the socket connection primitives, I think you'll find out what's happening to you pretty quick in this respect.

Upvotes: 1

Related Questions