You can easily extend the GrizzlyWebContainerFactory to support this requirement (since the class is final, I created a standalone utility that allows you to bind a listening socket to localhost). You can use this utility as:
SelectorThread threadSelector = GrizzlyWebContainerFactoryUtil.create("http://127.0.0.1:8080/", initParams, true);
Setting the last parameter to true causes it to bind to localhost. The only code I added to support this requirement is:
selectorThread.setAddress(InetAddress.getByName("localhost"));
The entire utility class is shown below:
import com.sun.grizzly.http.SelectorThread; import com.sun.grizzly.http.servlet.ServletAdapter; import com.sun.grizzly.standalone.StaticStreamAlgorithm; import com.sun.grizzly.tcp.Adapter; import com.sun.grizzly.tcp.http11.GrizzlyAdapter; import com.sun.jersey.api.container.ContainerException; import com.sun.jersey.api.core.ClasspathResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; import javax.servlet.Servlet; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URI; import java.util.Map; public class GrizzlyWebContainerFactoryUtil { public static SelectorThread create(String u, Map<String, String> initParams, boolean localHostOnly) throws IOException, IllegalArgumentException { if (u == null) throw new IllegalArgumentException("The URI must not be null"); return create(URI.create(u), initParams, localHostOnly); } public static SelectorThread create(URI u, Map<String, String> initParams, boolean localHostOnly) throws IOException { return create(u, ServletContainer.class, initParams, localHostOnly); } public static SelectorThread create(URI u, Class<? extends Servlet> c, Map<String, String> initParams, boolean localHostOnly) throws IOException { if (u == null) throw new IllegalArgumentException("The URI must not be null"); ServletAdapter adapter = new ServletAdapter(); if (initParams == null) { adapter.addInitParameter(ClasspathResourceConfig.PROPERTY_CLASSPATH, System.getProperty("java.class.path").replace(File.pathSeparatorChar, ';')); } else { for (Map.Entry<String, String> e : initParams.entrySet()) { adapter.addInitParameter(e.getKey(), e.getValue()); } } adapter.setServletInstance(getInstance(c)); String path = u.getPath(); if (path == null) throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be non-null"); else if (path.length() == 0) throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be present"); else if (path.charAt(0) != '/') throw new IllegalArgumentException("The URI path, of the URI " + u + ". must start with a '/'"); if (path.length() > 1) { if (path.endsWith("/")) path = path.substring(0, path.length() - 1); adapter.setContextPath(path); } return create(u, adapter, localHostOnly); } private static Servlet getInstance(Class<? extends Servlet> c) { try { return c.newInstance(); } catch (Exception e) { throw new ContainerException(e); } } public static SelectorThread create(URI u, Adapter adapter, boolean localHostOnly) throws IOException, IllegalArgumentException { if (u == null) throw new IllegalArgumentException("The URI must not be null");