You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Ph...@avivacanada.com on 2007/10/26 16:14:11 UTC

Compatible issue resolution of HttpClient and IBM WSAD environment

I am developing an application using HttpClient to access a HTTPS web 
application server in WSAD 5.1.2. But it failed because of IBM jsse does 
not support httpclient. I debugged this and find the reason. I made some 
change and it works fine.

The problem is in class com.avivacanada.commons.httpclient.protocol.
ReflectionSocketFactory

In method:

public static Socket createSocket(
        final String socketfactoryName, 
        final String host,
        final int port,
        final InetAddress localAddress,
        final int localPort,
        int timeout)
     throws IOException, UnknownHostException, ConnectTimeoutException

It tries to create a Socket using below steps
        //  SocketFactory socketFactory = 
Class.forName(socketfactoryName).getDefault();
        //  Socket socket = socketFactory.createSocket();
        //  SocketAddress localaddr = new InetSocketAddress(localAddress, 
localPort);
        //  SocketAddress remoteaddr = new InetSocketAddress(host, port);
        //  socket.bind(localaddr);
        //  socket.connect(remoteaddr, timeout);
        //  return socket;

But in WSAD environment, if using the default method of socketFactory to 
create socket, it failed: Socket socket = socketFactory.createSocket();

So, I changed the code as below:

            // Begin: changed by Philip She 
                        Object remoteaddr = InetAddress.getByName(host);
                        Object localaddr = localAddress;
                        if (localAddress == null) localaddr = 
InetAddress.getByName("localhost");
                        if (INETSOCKETADDRESS_CONSTRUCTOR == null) {
                                Class addressClass = Class.forName(
"java.net.InetSocketAddress");
                                INETSOCKETADDRESS_CONSTRUCTOR = 
addressClass.getConstructor(
                                        new Class[] { InetAddress.class, 
Integer.TYPE });
                        }
 
                        Object remoteSocketAddr = 
INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
                                new Object[] { 
InetAddress.getByName(host), new Integer(port)});

                        method = socketfactoryClass.getMethod(
"createSocket", 
                                new Class[] {InetAddress.class, 
Integer.TYPE, InetAddress.class, Integer.TYPE});
                        Socket socket = (Socket) 
method.invoke(socketfactory, new Object[] {remoteaddr, new 
Integer(port),localAddress, new Integer(localPort) });
                        if (SOCKETCONNECT_METHOD == null) {
                                SOCKETCONNECT_METHOD = Socket.class
.getMethod("connect", 
                                        new Class[] {Class.forName(
"java.net.SocketAddress"), Integer.TYPE});
                        }
                        SOCKETCONNECT_METHOD.invoke(socket, new Object[] { 
remoteSocketAddr, new Integer(timeout)});
                        // End: changed by Philip She 

Instead of below code, (I commented them). It works well.

//            method = socketfactoryClass.getMethod("createSocket", 
//                new Class[] {});
//            Socket socket = (Socket) method.invoke(socketfactory, new 
Object[] {});
// 
//            if (INETSOCKETADDRESS_CONSTRUCTOR == null) {
//                Class addressClass = 
Class.forName("java.net.InetSocketAddress");
//                INETSOCKETADDRESS_CONSTRUCTOR = 
addressClass.getConstructor(
//                    new Class[] { InetAddress.class, Integer.TYPE });
//            }
// 
//            Object remoteaddr = 
INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
//                new Object[] { InetAddress.getByName(host), new 
Integer(port)});
//
//            Object localaddr = 
INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
//                    new Object[] { localAddress, new 
Integer(localPort)});
//
//            if (SOCKETCONNECT_METHOD == null) {
//                SOCKETCONNECT_METHOD = Socket.class.getMethod("connect", 

//                    new Class[] 
{Class.forName("java.net.SocketAddress"), Integer.TYPE});
//            }
//
//            if (SOCKETBIND_METHOD == null) {
//                SOCKETBIND_METHOD = Socket.class.getMethod("bind", 
//                    new Class[] 
{Class.forName("java.net.SocketAddress")});
//            }
//            SOCKETBIND_METHOD.invoke(socket, new Object[] { localaddr});
//            SOCKETCONNECT_METHOD.invoke(socket, new Object[] { 
remoteaddr, new Integer(timeout)});

Best Regards,

Philip She

System Analyst
Web Services and Infrastructure Software -BSD
Aviva Canada Inc.,
2206 Eglinton Avenue East, Scarborough, On. M1L 4S8
Tel: 416-2882667