Problem:
I'm trying to get the dynamically selected HTTP port from OPS4J Pax Web within my application code at runtime.
Setup:
I have a custom Apache Karaf 4.4.0 distribution that installs the http Karaf Feature as a boot feature. The http Karaf Feature uses the OPS4J Pax Web implementation of the Http Service Specification with a Jetty web server. According to the Pax Web User Guide, the property org.osgi.service.http.port
in the configuration file org.ops4j.pax.web.cfg
has been set to 0
so that Pax Web automatically selects an HTTP port. This part works as expected.
Investigations:
I have tried the following approaches to read the HTTP port at runtime from different sources. Unfortunately, I wasn't successful with any of them.
Reading the property org.osgi.service.http.port
from the configuration file org.ops4j.pax.web.cfg
via the ConfigurationAdmin service resulted in the value 0
.
Reading the HTTP port via an injected HttpService (@Reference HttpService ...
) didn't work because the HttpService does not provide a method to get the HTTP port.
Reading the HTTP port via an injected WebContainer service from Pax Web (@Reference WebContainer ...
) didn't work because the WebContainer service does not provide a method to get the HTTP port.
Current workaround:
As a current workaround, I set the property org.osgi.service.http.port
in the configuration file org.ops4j.pax.web.cfg
for the root Karaf Container to a fixed value. For all child Karaf Containers, the property is commented out and the HTTP port is selected by a small code snippet and passed as a JVM argument before the child Karaf Containers are started via the InstanceService. This allows me to read the HTTP port as a system property (System.getProperty(...)
) in my application code.
However, I would like to make use of the possibility to let Pax Web automatically select an HTTP port, so maybe someone knows how the get the dynamically selected HTTP port at runtime.
Many thanks in advance.
Solution:
Thanks to Grzegorz Grzybek, I managed to get the dynamically selected HTTP port at runtime with the following code snippet:
@Reference
private HttpServiceRuntime httpServiceRuntime;
...
Map<String, Object> properties = httpServiceRuntime.getRuntimeDTO().serviceDTO.properties;
String[] localHttpEndpoints = (String[]) properties.get(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT);
URL localHttpEndpointUrl = new URL(localHttpEndpoints[0]);
int httpPort = localHttpEndpointUrl.getPort();
In Pax Web 8 (available since Karaf 4.4.0) you can grab an instance of org.osgi.service.http.runtime.HttpServiceRuntime
service and check its standard osgi.http.endpoint
property. In my case it was:
objectClass = [org.osgi.service.http.runtime.HttpServiceRuntime]
osgi.http.endpoint = [http://0.0.0.0:44067/]
osgi.http.service.id = [107]
service.bundleid = 70
service.changecount = 0
service.id = 108
service.scope = singleton
while the PID property was 0
:
karaf@root()> property-list --pid org.ops4j.pax.web
felix.fileinstall.filename = file:/data/servers/apache-karaf-4.4.1/etc/org.ops4j.pax.web.cfg
javax.servlet.context.tempdir = /data/servers/apache-karaf-4.4.1/data/pax-web/tmp
org.apache.karaf.features.configKey = org.ops4j.pax.web
org.osgi.service.http.enabled = true
org.osgi.service.http.port = 0
org.osgi.service.http.secure.enabled = false