Search code examples
javasocketspackagesecurityexception

How to implement a SocketImplFactory using systems default sockets


I have a small problem with implementing a own SocketImplFactory in Java. My goal is to write a factory which offers me a way to close all open sockets with one simple method call. So I only want to have a kind of "proxy factory" which stores all the created sockets in a list. On this list I could perform all the actions I need.

I tried to implement it like this:

package java.net;

import java.io.IOException;
import java.net.SocketImpl;
import java.net.SocketImplFactory;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.crosscloud.applicationlayer.logger.CCLogger;


public class CCSocketImplFactory implements SocketImplFactory
{
    private List<SocketImpl> _openSockets; 

    public CCSocketImplFactory()
    {
        _openSockets = new LinkedList<>();
    }

    @Override
    public SocketImpl createSocketImpl()
    {
        SocketImpl impl = new SocksSocketImpl();
        _openSockets.add(impl);
        return impl;
    }

    public void closeAll()
    {
        _openSockets.forEach((socket)->
        {
            try
            {
                socket.close();
            }
            catch (Exception e)
            {
                logException(this, e);
            }
        });
    }

    public static CCSocketImplFactory register()
    {
        CCSocketImplFactory fact =  new CCSocketImplFactory();
        try
        {
            Socket.setSocketImplFactory(fact);
        }
        catch (IOException e)
        {
            logException(CCSocketImplFactory.class, e);
        }
        return fact;
    }

The problem I have now is that I have to create the class in the package java.net because the class SocksSocketImpl(In my opinion this should be the standard type) is only visible in this package.

When I now want to run the code I get a SecurityException because the package name is probhibited.

Is there a workaround for my problem? Thank you!


Solution

  • It appears that you are trying to use only one class from java.net There is no need to move you class tot hat package just to create an instance of it. I suggest using reflection instead.

    Constructor cons = Class.forName("java.net.SocksSocketImpl").getDeclaredConstructor();
    cons.setAccessible(true);
    SocketImpl si = (SocketImpl) cons.newInstance();
    

    However using SOCKS by default is likely to be a bad idea as it will change the default not just for your sockets, but all sockets even ones for internal use such as JMX or VisualVM.