Issue #3162 - Attempting to address ServiceLoader with javax.websocket (client) on OSGi

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
Joakim Erdfelt 2018-12-04 11:31:02 -06:00
parent 7262bfd584
commit 435dd200bd
3 changed files with 44 additions and 32 deletions

View File

@ -48,6 +48,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import aQute.bnd.osgi.Constants; import aQute.bnd.osgi.Constants;
import org.osgi.framework.BundleException;
/** /**
* Test using websocket in osgi * Test using websocket in osgi
@ -64,6 +65,7 @@ public class TestJettyOSGiBootWithJavaxWebSocket
public static Option[] configure() public static Option[] configure()
{ {
ArrayList<Option> options = new ArrayList<>(); ArrayList<Option> options = new ArrayList<>();
options.add(TestOSGiUtil.optionalRemoteDebug());
options.add(CoreOptions.junitBundles()); options.add(CoreOptions.junitBundles());
options.addAll(TestOSGiUtil.configureJettyHomeAndPort(false, "jetty-http-boot-with-javax-websocket.xml")); options.addAll(TestOSGiUtil.configureJettyHomeAndPort(false, "jetty-http-boot-with-javax-websocket.xml"));
options.add(CoreOptions.bootDelegationPackages("org.xml.sax", "org.xml.*", "org.w3c.*", "javax.sql.*","javax.xml.*", "javax.activation.*")); options.add(CoreOptions.bootDelegationPackages("org.xml.sax", "org.xml.*", "org.w3c.*", "javax.sql.*","javax.xml.*", "javax.activation.*"));
@ -111,35 +113,14 @@ public class TestJettyOSGiBootWithJavaxWebSocket
TestOSGiUtil.debugBundles(bundleContext); TestOSGiUtil.debugBundles(bundleContext);
} }
@Test @Test
public void testWebsocket() throws Exception public void testWebsocket() throws Exception
{ {
//this is necessary because the javax.websocket-api jar does not have manifest headers fixJavaxWebSocketApi();
//that allow it to use ServiceLoader in osgi, this corrects that defect
TinyBundle bundle = TinyBundles.bundle();
bundle.set(Constants.FRAGMENT_HOST, "javax.websocket-api");
bundle.set(Constants.REQUIRE_CAPABILITY,
"osgi.serviceloader;filter:=\"(osgi.serviceloader=javax.websocket.ContainerProvider)\";resolution:=optional;cardinality:=multiple, osgi.extender; filter:=\"(osgi.extender=osgi.serviceloader.processor)\"");
bundle.set(Constants.BUNDLE_SYMBOLICNAME, "javax.websocket.api.fragment");
InputStream is = bundle.build(TinyBundles.withBnd());
bundleContext.installBundle("dummyLocation", is);
Bundle websocketApiBundle = TestOSGiUtil.getBundle(bundleContext, "javax.websocket-api");
assertNotNull(websocketApiBundle);
websocketApiBundle.update();
websocketApiBundle.start();
Bundle javaxWebsocketClient = TestOSGiUtil.getBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket");
assertNotNull(javaxWebsocketClient);
javaxWebsocketClient.start();
Bundle javaxWebsocketServer = TestOSGiUtil.getBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.server");
assertNotNull(javaxWebsocketServer);
javaxWebsocketServer.start();
startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.common");
startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.client");
startBundle(bundleContext, "org.eclipse.jetty.websocket.javax.websocket.server");
String port = System.getProperty("boot.javax.websocket.port"); String port = System.getProperty("boot.javax.websocket.port");
assertNotNull(port); assertNotNull(port);
@ -148,7 +129,7 @@ public class TestJettyOSGiBootWithJavaxWebSocket
assertNotNull(container); assertNotNull(container);
SimpleJavaxWebSocket socket = new SimpleJavaxWebSocket(); SimpleJavaxWebSocket socket = new SimpleJavaxWebSocket();
URI uri = new URI("ws://127.0.0.1:" + port+"/javax.websocket/"); URI uri = new URI("ws://127.0.0.1:" + port + "/javax.websocket/");
Session session = container.connectToServer(socket,uri); Session session = container.connectToServer(socket,uri);
try try
{ {
@ -163,4 +144,29 @@ public class TestJettyOSGiBootWithJavaxWebSocket
assertTrue(socket.closeLatch.await(1,TimeUnit.SECONDS)); // give remote 1 second to acknowledge response assertTrue(socket.closeLatch.await(1,TimeUnit.SECONDS)); // give remote 1 second to acknowledge response
} }
} }
private void fixJavaxWebSocketApi() throws BundleException
{
// this is necessary because the javax.websocket-api jar does not have manifest headers
// that allow it to use ServiceLoader in osgi, this corrects that defect
TinyBundle bundle = TinyBundles.bundle();
bundle.set(Constants.FRAGMENT_HOST, "javax.websocket-api");
bundle.set(Constants.REQUIRE_CAPABILITY,
"osgi.serviceloader;filter:=\"(osgi.serviceloader=javax.websocket.ContainerProvider)\";resolution:=optional;cardinality:=multiple, osgi.extender; filter:=\"(osgi.extender=osgi.serviceloader.processor)\"");
bundle.set(Constants.BUNDLE_SYMBOLICNAME, "javax.websocket.api.fragment");
InputStream is = bundle.build(TinyBundles.withBnd());
bundleContext.installBundle("dummyLocation", is);
Bundle websocketApiBundle = TestOSGiUtil.getBundle(bundleContext, "javax.websocket-api");
assertNotNull(websocketApiBundle);
websocketApiBundle.update();
websocketApiBundle.start();
}
private void startBundle(BundleContext bundleContext, String symbolicName) throws BundleException
{
Bundle bundle = TestOSGiUtil.getBundle(bundleContext, symbolicName);
assertNotNull("Bundle[" + symbolicName + "] should exist",bundle);
bundle.start();
}
} }

View File

@ -13,7 +13,7 @@
<name>Jetty :: Websocket :: javax.websocket :: Client Implementation</name> <name>Jetty :: Websocket :: javax.websocket :: Client Implementation</name>
<properties> <properties>
<bundle-symbolic-name>${project.groupId}.javax.websocket</bundle-symbolic-name> <bundle-symbolic-name>${project.groupId}.javax.websocket.client</bundle-symbolic-name>
</properties> </properties>
<dependencies> <dependencies>
@ -53,10 +53,15 @@
<instructions> <instructions>
<Bundle-Description>javax.websocket.client Implementation</Bundle-Description> <Bundle-Description>javax.websocket.client Implementation</Bundle-Description>
<Export-Package> <Export-Package>
org.eclipse.jetty.websocket.jsr356.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" org.eclipse.jetty.websocket.jsr356.client.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
</Export-Package> </Export-Package>
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional</Require-Capability> <Require-Capability>
<Provide-Capability>osgi.serviceloader;osgi.serviceloader=javax.websocket.ContainerProvider</Provide-Capability> osgi.extender;
filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional
</Require-Capability>
<Provide-Capability>
osgi.serviceloader;osgi.serviceloader=javax.websocket.ContainerProvider
</Provide-Capability>
</instructions> </instructions>
</configuration> </configuration>
</execution> </execution>

View File

@ -74,6 +74,7 @@
filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional
</Require-Capability> </Require-Capability>
<Provide-Capability> <Provide-Capability>
osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.webapp.Configuration,
osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer, osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,
osgi.serviceloader;osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator osgi.serviceloader;osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator
</Provide-Capability> </Provide-Capability>