Hi Lukasz,

I checked your diff, with some changes everything regarding the versions is
running fine now. :)
Take a look at the attached patch.
All integration tests are failing though, so it seems your changes aren't
complete. Might that be the reason your own tests aren't working correctly?

regards, Achim


2017-06-30 22:57 GMT+02:00 Achim Nierbeck <[email protected]>:

> Hi Lukasz,
>
> this is definitely the right list to ask for.
> Right now I don't have much time or energy to look at your issue in a
> closer detail.
> If in doubt about how a shared context is about to work, please take a
> look at the samples and / or the integration tests.
> There are some available and I hope they make some of your questions
> clearer. If not I might have some more free cycles and a clearer mind about
> that next week ...
>
> regards, Achim
>
>
> 2017-06-30 11:23 GMT+02:00 Lukasz Lech <[email protected]>:
>
>> Hello,
>>
>>
>>
>> I hope this group is appropriate for asking this question, if not, my
>> apologize and please suggest if there is appropriate place to ask.
>>
>>
>>
>> I’ve submitted the issue https://ops4j1.jira.com/browse/PAXWEB-1105
>> because I need to register session listener for WebServices created by
>> JaxrsPublisher.
>>
>>
>>
>> I’ve added parameter doing what is described in the issue, and after
>> deploying and modifying configuration file, the shared http context
>> instance is returned upon createDefaultHttpContext() call. (I’ve included
>> the git diff of changes I’ve made locally).
>>
>>
>>
>> 2 bundles: jaxrs publisher and my session listener registrator are
>> connected to http service:
>>
>> 2017-06-30T10:46:18,768 | INFO  | pool-3-thread-1  |
>> HttpServiceFactoryImpl           | 199 - org.ops4j.pax.web.pax-web-runtime
>> - 6.1.0.SNAPSHOT | Binding bundle: [com.eclipsesource.jaxrs.publisher
>> [14]] to http service
>>
>> 2017-06-30T10:46:20,644 | INFO  | pool-3-thread-1  |
>> HttpServiceFactoryImpl           | 199 - org.ops4j.pax.web.pax-web-runtime
>> - 6.1.0.SNAPSHOT | Binding bundle: [pax-web-configurator [204]] to http
>> service
>>
>>
>>
>> Jaxrs publisher registers servlet:
>>
>> 2017-06-30T10:46:20,010 | INFO  | pool-3-thread-1  |
>> HttpServiceStarted               | 199 - org.ops4j.pax.web.pax-web-runtime
>> - 6.1.0.SNAPSHOT | Register servlet (alias=/services). Using context
>> [ContextModel{id=org.ops4j.pax.web.service.spi.model.Context
>> Model-5,name=,httpContext=org.ops4j.pax.web.service.
>> internal.DefaultSharedWebContainerContext@f7bb2fe,
>> contextParams={},virtualHosts={},connectors={}}]
>>
>>
>>
>> My stuff registers session listener and session attribute listener:
>>
>> 2017-06-30T10:46:20,645 | INFO  | pool-3-thread-1  |
>> HttpServiceStarted               | 199 - org.ops4j.pax.web.pax-web-runtime
>> - 6.1.0.SNAPSHOT | Register event listener (listener=com.riag.taxcloud.da
>> tamodel.channel.DatamodelSessionListener@18b607f1). Using context
>> [ContextModel{id=org.ops4j.pax.web.service.spi.model.Context
>> Model-11,name=,httpContext=org.ops4j.pax.web.service.
>> internal.DefaultSharedWebContainerContext@4f5b090a,
>> contextParams={},virtualHosts={},connectors={}}]
>>
>> 2017-06-30T10:46:20,655 | INFO  | pool-3-thread-1  |
>> HttpServiceStarted               | 199 - org.ops4j.pax.web.pax-web-runtime
>> - 6.1.0.SNAPSHOT | Register event listener (listener=com.riag.taxcloud.da
>> tamodel.channel.DatamodelSessionAttributeListener@7e902b64). Using
>> context [ContextModel{id=org.ops4j.pax.web.service.spi.model.Context
>> Model-13,name=,httpContext=org.ops4j.pax.web.service.
>> internal.DefaultSharedWebContainerContext@56ba6785,
>> contextParams={},virtualHosts={},connectors={}}]
>>
>>
>>
>> This is how I register/unregister listeners:
>>
>>        *public* *void* bindSessionListener(HttpSessionListener listener)
>> {
>>
>>              *LOGGER*.info("bindSessionListener {}", listener);
>>
>>              webContainer.registerEventListener(listener, *null*);
>>
>>              //servletContext.addListener(listener);
>> IllegalStateException
>>
>>        }
>>
>>
>>
>>        *public* *void* unbindSessionListener(HttpSessionListener listener)
>> {
>>
>>              *LOGGER*.info("unbindSessionListener {}", listener);
>>
>>              *if* (listener == *null*)
>>
>>                     *return*;
>>
>>              webContainer.unregisterEventListener(listener);
>>
>>        }
>>
>>
>>
>>
>>
>>        *public* *void* 
>> bindSessionAttributeListener(HttpSessionAttributeListener
>> listener) {
>>
>>              *LOGGER*.info("bindSessionAttributeListener {}", listener);
>>
>>              webContainer.registerEventListener(listener, *null*);
>>
>>              // servletContext.addListener(listener);
>> IllegalStateException
>>
>>        }
>>
>>
>>
>>        *public* *void* 
>> unbindSessionAttributeListener(HttpSessionAttributeListener
>> listener) {
>>
>>              *LOGGER*.info("unbindSessionAttributeListener {}", listener
>> );
>>
>>              *if* (listener == *null*)
>>
>>                     *return*;
>>
>>              webContainer.unregisterEventListener(listener);
>>
>>        }
>>
>>
>>
>> <?xml version=*"1.0"* encoding=*"UTF-8"*?>
>>
>> <blueprint xmlns=*"http://www.osgi.org/xmlns/blueprint/v1.0.0
>> <http://www.osgi.org/xmlns/blueprint/v1.0.0>"*
>>
>>              
>> xmlns:ext=*"http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0
>> <http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0>"*
>>
>>              
>> xmlns:cm=*"http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0
>> <http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0>"*>
>>
>>
>>
>>        <bean id=*"paxWebConfigurator"* class=
>> *"com.riag.taxcloud.paxweb.configurator.PaxWebSessionConfigurator"*>
>>
>>                     <property name=*"context"* ref=
>> *"blueprintBundleContext"* />
>>
>>                     <property name=*"webContainer"* ref=*"webContainer"*
>> />
>>
>>                     <property name=*"servletConfiguration"* ref=
>> *"jaxRsServletConfiguration"*/>
>>
>>                     <property name=*"servletContext"* ref=
>> *"jaxbServletContext"*/>
>>
>>        </bean>
>>
>>
>>
>>        <reference id=*"webContainer"* interface=
>> *"org.ops4j.pax.web.service.WebContainer"*/>
>>
>>
>>
>>        <reference-list id=*"sessionListeners"* interface=
>> *"javax.servlet.http.HttpSessionListener"* availability=*"optional"*>
>>
>>              <reference-listener bind-method=*"bindSessionListener"*
>> unbind-method=*"unbindSessionListener"* ref=*"paxWebConfigurator"* />
>>
>>        </reference-list>
>>
>>
>>
>>        <reference-list id=*"sessionAttributeListeners"* interface=
>> *"javax.servlet.http.HttpSessionAttributeListener"* availability=
>> *"optional"*>
>>
>>              <reference-listener bind-method=
>> *"bindSessionAttributeListener"* unbind-method=
>> *"unbindSessionAttributeListener"* ref=*"paxWebConfigurator"* />
>>
>>        </reference-list>
>>
>>
>>
>> </blueprint>
>>
>>
>>
>> However, the session listener is not called when new session is created
>> by WebService call. I’ve set a breakpoint within
>> org.eclipse.jetty.server.session.AbstractSessionManager.addSession(AbstractSession,
>> boolean) and _sessionListeners list is empty.
>>
>>
>>
>> Do I get something conceptually wrong? I thought that if both bundles
>> will register stuff using the same HttpContext, one of them could register
>> listener that would listen to events for servlets created by the second one.
>>
>> Is the concept of bundles working with different HttpContext somehow
>> deeply build-in in pax-web so I can’t change that behavior with such simple
>> ‘hack’?
>>
>>
>>
>> Anyway, my patch (after cleanup – I’ve increased log level to see what
>> happens and commented out the baselining so that I’m able to compile with
>> maven) seems to solve the JIRA issue. However I’m not sure if the JIRA
>> issue solves any issue, or I lack understanding the concept of ‘shared’ and
>> ‘non-shared’ HttpContext in pax-web….
>>
>>
>>
>> Best regards,
>>
>> Lukasz Lech
>>
>>
>>
>> --
>> --
>> ------------------
>> OPS4J - http://www.ops4j.org - [email protected]
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "OPS4J" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> --
>
> Apache Member
> Apache Karaf <http://karaf.apache.org/> Committer & PMC
> OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer &
> Project Lead
> blog <http://notizblog.nierbeck.de/>
> Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>
>
> Software Architect / Project Manager / Scrum Master
>
>


-- 

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer &
Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Software Architect / Project Manager / Scrum Master

-- 
-- 
------------------
OPS4J - http://www.ops4j.org - [email protected]

--- 
You received this message because you are subscribed to the Google Groups 
"OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/PAXWEB-1105.diff b/PAXWEB-1105.diff
new file mode 100644
index 0000000..326a9ee
--- /dev/null
+++ b/PAXWEB-1105.diff
@@ -0,0 +1,146 @@
+diff --git 
a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
 
b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
+index b1113d3..2c73528 100644
+--- 
a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
++++ 
b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
+@@ -118,6 +118,7 @@ public interface WebContainerConstants {
+       String PROPERTY_SESSION_COOKIE_SECURE = PID + ".session.cookie.secure";
+       String PROPERTY_SESSION_LAZY_LOAD = PID + ".session.lazyload";
+       String PROPERTY_SESSION_STORE_DIRECTORY = PID + 
".session.storedirectory";
++      String PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT = PID + 
".context.useSharedPerDefault";
+ 
+       String PROPERTY_TEMP_DIR = "javax.servlet.context.tempdir";
+ 
+diff --git 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
+index aa9b38b..d5dc7ba 100644
+--- 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
++++ 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
+@@ -49,6 +49,7 @@ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_L
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_STORE_DIRECTORY;
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_TIMEOUT;
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_URL;
++import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT;
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_CLIENT_AUTH_NEEDED;
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_CLIENT_AUTH_WANTED;
+ import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_KEYPASSWORD;
+@@ -502,6 +503,11 @@ public class ConfigurationImpl extends PropertyStore 
implements Configuration {
+       public String getSessionStoreDirectory() {
+               return 
getResolvedStringProperty(PROPERTY_SESSION_STORE_DIRECTORY);
+       }
++      
++      @Override
++      public Boolean isUseSharedHttpContextByDefault() {
++              return 
getResolvedBooleanProperty(PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT);
++      }
+ 
+       @Override
+       public String getWorkerName() {
+diff --git 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
+index 7ce6394..d998271 100644
+--- 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
++++ 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
+@@ -214,7 +214,7 @@ class HttpServiceStarted implements StoppableHttpService {
+                                                               final 
HttpContext httpContext) throws ServletException,
+                       NamespaceException {
+               final ContextModel contextModel = 
getOrCreateContext(httpContext);
+-              LOG.debug("Register servlet (alias={}). Using context [{}]", 
alias, contextModel);
++              LOG.info("Register servlet (alias={}). Using context [{}]", 
alias, contextModel);
+               @SuppressWarnings("unchecked")
+               final ServletModel model = new ServletModel(contextModel, 
servlet,
+                               alias, initParams, loadOnStartup, 
asyncSupported);
+@@ -323,7 +323,13 @@ class HttpServiceStarted implements StoppableHttpService {
+ 
+       @Override
+       public WebContainerContext createDefaultHttpContext() {
+-              return new DefaultHttpContext(serviceBundle, 
WebContainerContext.DefaultContextIds.DEFAULT.getValue());
++              if 
(serverController.getConfiguration().isUseSharedHttpContextByDefault()) {
++                      LOG.info("createDefaultHttpContext returns 
SharedContext");
++                      return createDefaultSharedHttpContext();
++              } else {
++                      LOG.info("createDefaultHttpContext returns HttpContext 
for bundle {}", serviceBundle.getBundleId());
++                      return 
createDefaultHttpContext(WebContainerContext.DefaultContextIds.DEFAULT.getValue());
++              }       
+       }
+ 
+       @Override
+@@ -495,7 +501,7 @@ class HttpServiceStarted implements StoppableHttpService {
+       public void registerEventListener(final EventListener listener,
+                                                                         final 
HttpContext httpContext) {
+               final ContextModel contextModel = 
getOrCreateContext(httpContext);
+-              LOG.debug("Register event listener (listener={}). Using context 
[{}]", listener, contextModel);
++              LOG.info("Register event listener (listener={}). Using context 
[{}]", listener, contextModel);
+               final EventListenerModel model = new 
EventListenerModel(contextModel,
+                               listener);
+               boolean serviceSuccess = false;
+diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
+index 503aaf0..0548b55 100644
+--- 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
++++ 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
+@@ -129,6 +129,20 @@ public interface Configuration {
+       String getSessionStoreDirectory();
+ 
+       Boolean getSessionLazyLoad();
++      
++      /**
++       * The user of method 
org.osgi.service.http.HttpService.createDefaultHttpContext() is usually
++       * (and should not be) aware of implementation used, so they can't call 
++       * 
org.ops4j.pax.web.service.WebContainer.createDefaultSharedHttpContext() 
++       * if they want to use shared context. <br/>
++       * Therefore we provide a configuration parameter that controls the 
behavior of publicly available
++       * method createDefaultHttpContext(). <br/>
++       * If the parameter is not set, or is set to false, the per-bundle 
HttpContext is returned, as
++       * in pre-6.1.0 versions. When it is set to true, the shared instance 
is returned.
++       * 
++       * @return true if should use shared HttpContext by default.
++       */
++      Boolean isUseSharedHttpContextByDefault();
+ 
+       String getWorkerName();
+ 
+diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
+index e684627..47954a4 100644
+--- 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
++++ 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
+@@ -14,7 +14,7 @@ See the License for the specific language governing 
permissions and
+ limitations under the License.
+  */
+ 
+-@Version("6.0.0")
++@Version("6.1.0")
+ package org.ops4j.pax.web.service.spi.model;
+ 
+ import org.osgi.annotation.versioning.Version;
+diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
+index aabdd42..3df93db 100644
+--- 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
++++ 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
+@@ -14,7 +14,7 @@ See the License for the specific language governing 
permissions and
+ limitations under the License.
+  */
+ 
+-@Version("6.0.0")
++@Version("6.1.0")
+ package org.ops4j.pax.web.service.spi.util;
+ 
+ import org.osgi.annotation.versioning.Version;
+diff --git a/pom.xml b/pom.xml
+index cd6de08..d0df22d 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -294,7 +294,7 @@
+                                                               
<obrRepository>NONE</obrRepository>
+                                                       </configuration>
+                                               </execution>
+-                                              <execution>
++                                              <!--execution>
+                                                       <id>baseline</id>
+                                                       <goals>
+                                                               
<goal>baseline</goal>
+@@ -303,7 +303,7 @@
+                                                               
<comparisonVersion>${baseline.version}</comparisonVersion>
+                                                               
<failOnWarning>false</failOnWarning>
+                                                       </configuration>
+-                                              </execution>
++                                              </execution-->
+                                               <execution>
+                                                       <id>cleanVersions</id>
+                                                       
<phase>generate-sources</phase>
diff --git a/Websocket_Patch.patch b/Websocket_Patch.patch
new file mode 100644
index 0000000..6942f00
--- /dev/null
+++ b/Websocket_Patch.patch
@@ -0,0 +1,235 @@
+Index: 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardSetup.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardSetup.java
     (revision )
++++ 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardSetup.java
     (revision )
+@@ -0,0 +1,57 @@
++/*
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ * implied.
++ *
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.ops4j.pax.web.itest.jetty.external;
++
++import org.junit.runner.RunWith;
++import org.ops4j.pax.exam.Configuration;
++import org.ops4j.pax.exam.Option;
++import org.ops4j.pax.exam.junit.PaxExam;
++import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
++import org.ops4j.pax.exam.spi.reactors.PerClass;
++import org.ops4j.pax.web.itest.base.AbstractTestBase;
++import org.ops4j.pax.web.itest.jetty.ITestBase;
++import org.ops4j.pax.web.itest.jetty.support.SimpleWebSocket;
++import org.osgi.framework.Constants;
++
++import static org.ops4j.pax.exam.CoreOptions.streamBundle;
++import static org.ops4j.pax.exam.OptionUtils.combine;
++import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;
++
++@RunWith(PaxExam.class)
++@ExamReactorStrategy(PerClass.class)
++public class WebSocketWhiteBoardSetup extends ITestBase {
++
++    @Configuration
++    public static Option[] configure() {
++        return combine(
++                configureWebSocketJetty(),
++                streamBundle(bundle()
++                        .add(SimpleWebSocket.class)
++                        .add(WebsocketBundleActivator.class)
++                        .add(AbstractTestBase.class)
++                        .add(WebSocketWhiteBoardSetup.class)
++                        .add(ITestBase.class)
++                        .set(Constants.BUNDLE_SYMBOLICNAME, 
"WebsocketStartupBundle")
++                        .set(Constants.BUNDLE_ACTIVATOR, 
WebsocketBundleActivator.class.getName())
++                        .set(Constants.EXPORT_PACKAGE, 
"org.ops4j.pax.web.itest.jetty.external")
++                        .set(Constants.DYNAMICIMPORT_PACKAGE, "*")
++                        .build()
++                )
++        );
++    }
++
++
++}
+Index: 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebsocketBundleActivator.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebsocketBundleActivator.java
     (revision )
++++ 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebsocketBundleActivator.java
     (revision )
+@@ -0,0 +1,37 @@
++/*
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ * implied.
++ *
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.ops4j.pax.web.itest.jetty.external;
++
++import org.ops4j.pax.web.itest.jetty.support.SimpleWebSocket;
++import org.osgi.framework.BundleActivator;
++import org.osgi.framework.BundleContext;
++import org.osgi.framework.ServiceRegistration;
++
++public class WebsocketBundleActivator implements BundleActivator {
++    private ServiceRegistration<?> serviceRegistration;
++
++    @Override
++    public void start(BundleContext context) throws Exception {
++        SimpleWebSocket simpleWebSocket = new SimpleWebSocket();
++        serviceRegistration = context.registerService(Object.class.getName(), 
simpleWebSocket, null);
++    }
++
++    @Override
++    public void stop(BundleContext context) throws Exception {
++        if (serviceRegistration != null)
++            serviceRegistration.unregister();
++    }
++}
+Index: 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardIntegrationTest.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardIntegrationTest.java
   (revision )
++++ 
pax-web-itest/pax-web-itest-container/pax-web-itest-container-jetty/src/test/java/org/ops4j/pax/web/itest/jetty/external/WebSocketWhiteBoardIntegrationTest.java
   (revision )
+@@ -0,0 +1,117 @@
++/*
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ * implied.
++ *
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.ops4j.pax.web.itest.jetty.external;
++
++import org.eclipse.jetty.websocket.api.Session;
++import org.eclipse.jetty.websocket.api.StatusCode;
++import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
++import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
++import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
++import org.eclipse.jetty.websocket.api.annotations.WebSocket;
++import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
++import org.eclipse.jetty.websocket.client.WebSocketClient;
++import org.junit.ClassRule;
++import org.junit.Test;
++import org.ops4j.pax.exam.junit.PaxExamServer;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++import java.net.URI;
++import java.util.concurrent.CountDownLatch;
++import java.util.concurrent.Future;
++import java.util.concurrent.TimeUnit;
++
++
++public class WebSocketWhiteBoardIntegrationTest {
++
++    private static final Logger LOG = 
LoggerFactory.getLogger(WebSocketWhiteBoardIntegrationTest.class);
++
++    @ClassRule
++    public static PaxExamServer exam = new 
PaxExamServer(WebSocketWhiteBoardSetup.class);
++
++
++    @Test
++    public void testWebsocket() throws Exception {
++        String destUri = "ws://localhost:8181/simple";
++        WebSocketClient client = new WebSocketClient();
++        SimpleEchoSocket socket = new SimpleEchoSocket();
++        try {
++            client.start();
++
++            URI echoUri = new URI(destUri);
++            ClientUpgradeRequest request = new ClientUpgradeRequest();
++            client.connect(socket, echoUri, request);
++            System.out.printf("Connecting to : %s%n", echoUri);
++
++            // wait for closed socket connection.
++            socket.awaitClose(5, TimeUnit.SECONDS);
++        } finally {
++            try {
++                client.stop();
++            } catch (Exception e) {
++                e.printStackTrace();
++            }
++        }
++    }
++
++
++    @WebSocket(maxTextMessageSize = 64 * 1024)
++    public class SimpleEchoSocket {
++        private final CountDownLatch closeLatch;
++        @SuppressWarnings("unused")
++        private Session session;
++
++        public SimpleEchoSocket() {
++            this.closeLatch = new CountDownLatch(1);
++        }
++
++        public boolean awaitClose(int duration, TimeUnit unit) throws 
InterruptedException {
++            return this.closeLatch.await(duration, unit);
++        }
++
++        @OnWebSocketClose
++        public void onClose(int statusCode, String reason) {
++            System.out.printf("Connection closed: %d - %s%n", statusCode, 
reason);
++            this.session = null;
++            this.closeLatch.countDown(); // trigger latch
++        }
++
++        @OnWebSocketConnect
++        public void onConnect(Session session) {
++            System.out.printf("Got connect: %s%n", session);
++            this.session = session;
++            try {
++                Future<Void> fut;
++                fut = session.getRemote().sendStringByFuture("Hello");
++                fut.get(2, TimeUnit.SECONDS); // wait for send to complete.
++
++                fut = session.getRemote().sendStringByFuture("Thanks for the 
conversation.");
++                fut.get(2, TimeUnit.SECONDS); // wait for send to complete.
++
++                session.close(StatusCode.NORMAL, "I'm done");
++            } catch (Throwable t) {
++                t.printStackTrace();
++            }
++        }
++
++        @OnWebSocketMessage
++        public void onMessage(String msg) {
++            System.out.printf("Got msg: %s%n", msg);
++        }
++    }
++
++}
++
diff --git 
a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
 
b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
index b1113d3..2c73528 100644
--- 
a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
+++ 
b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerConstants.java
@@ -118,6 +118,7 @@
        String PROPERTY_SESSION_COOKIE_SECURE = PID + ".session.cookie.secure";
        String PROPERTY_SESSION_LAZY_LOAD = PID + ".session.lazyload";
        String PROPERTY_SESSION_STORE_DIRECTORY = PID + 
".session.storedirectory";
+       String PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT = PID + 
".context.useSharedPerDefault";
 
        String PROPERTY_TEMP_DIR = "javax.servlet.context.tempdir";
 
diff --git a/pax-web-runtime/pom.xml b/pax-web-runtime/pom.xml
index 1e89569..836d24b 100644
--- a/pax-web-runtime/pom.xml
+++ b/pax-web-runtime/pom.xml
@@ -65,9 +65,9 @@
                                                        
org.ops4j.pax.web.service; version="${pax-web.osgi.version}"; 
resolution:=required,
                                                        
org.ops4j.pax.web.service.whiteboard; version="${pax-web.osgi.version}"; 
resolution:=required,
                                                        
org.ops4j.pax.web.utils; version="${pax-web.osgi.version}"; 
resolution:=required,
-                                                       
org.ops4j.pax.web.service.spi; version="${pax-web.osgi.version}"; 
resolution:=required,
-                                                       
org.ops4j.pax.web.service.spi.model; version="${pax-web.osgi.version}"; 
resolution:=required,
-                                                       
org.ops4j.pax.web.service.spi.util; version="${pax-web.osgi.version}"; 
resolution:=required,
+                                                       
org.ops4j.pax.web.service.spi; version="${pax-web.osgi.version}"; 
resolution:=required; provide:=true,
+                                                       
org.ops4j.pax.web.service.spi.model; version="${pax-web.osgi.version}"; 
resolution:=required; provide:=true,
+                                                       
org.ops4j.pax.web.service.spi.util; version="${pax-web.osgi.version}"; 
resolution:=required; provide:=true,
                                                        javax.servlet; 
version="[2.3.0,4.0.0)",
                                                        javax.servlet.http; 
version="[2.3.0,4.0.0)",
                                                        javax.xml.parsers,
diff --git 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
index aa9b38b..d5dc7ba 100644
--- 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
+++ 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/ConfigurationImpl.java
@@ -49,6 +49,7 @@
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_STORE_DIRECTORY;
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_TIMEOUT;
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SESSION_URL;
+import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT;
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_CLIENT_AUTH_NEEDED;
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_CLIENT_AUTH_WANTED;
 import static 
org.ops4j.pax.web.service.WebContainerConstants.PROPERTY_SSL_KEYPASSWORD;
@@ -502,6 +503,11 @@
        public String getSessionStoreDirectory() {
                return 
getResolvedStringProperty(PROPERTY_SESSION_STORE_DIRECTORY);
        }
+       
+       @Override
+       public Boolean isUseSharedHttpContextByDefault() {
+               return 
getResolvedBooleanProperty(PROPERTY_USE_SHARED_HTTPCONTEXT_PER_DEFAULT);
+       }
 
        @Override
        public String getWorkerName() {
diff --git 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
index 7ce6394..d998271 100644
--- 
a/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
+++ 
b/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java
@@ -214,7 +214,7 @@
                                                                final 
HttpContext httpContext) throws ServletException,
                        NamespaceException {
                final ContextModel contextModel = 
getOrCreateContext(httpContext);
-               LOG.debug("Register servlet (alias={}). Using context [{}]", 
alias, contextModel);
+               LOG.info("Register servlet (alias={}). Using context [{}]", 
alias, contextModel);
                @SuppressWarnings("unchecked")
                final ServletModel model = new ServletModel(contextModel, 
servlet,
                                alias, initParams, loadOnStartup, 
asyncSupported);
@@ -323,7 +323,13 @@
 
        @Override
        public WebContainerContext createDefaultHttpContext() {
-               return new DefaultHttpContext(serviceBundle, 
WebContainerContext.DefaultContextIds.DEFAULT.getValue());
+               if 
(serverController.getConfiguration().isUseSharedHttpContextByDefault()) {
+                       LOG.info("createDefaultHttpContext returns 
SharedContext");
+                       return createDefaultSharedHttpContext();
+               } else {
+                       LOG.info("createDefaultHttpContext returns HttpContext 
for bundle {}", serviceBundle.getBundleId());
+                       return 
createDefaultHttpContext(WebContainerContext.DefaultContextIds.DEFAULT.getValue());
+               }       
        }
 
        @Override
@@ -495,7 +501,7 @@
        public void registerEventListener(final EventListener listener,
                                                                          final 
HttpContext httpContext) {
                final ContextModel contextModel = 
getOrCreateContext(httpContext);
-               LOG.debug("Register event listener (listener={}). Using context 
[{}]", listener, contextModel);
+               LOG.info("Register event listener (listener={}). Using context 
[{}]", listener, contextModel);
                final EventListenerModel model = new 
EventListenerModel(contextModel,
                                listener);
                boolean serviceSuccess = false;
diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
index 503aaf0..f091be8 100644
--- a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
+++ b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/Configuration.java
@@ -20,6 +20,9 @@
 import java.net.URL;
 import java.util.List;
 
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
 public interface Configuration {
 
        Boolean useNIO();
@@ -129,6 +132,20 @@
        String getSessionStoreDirectory();
 
        Boolean getSessionLazyLoad();
+       
+       /**
+        * The user of method 
org.osgi.service.http.HttpService.createDefaultHttpContext() is usually
+        * (and should not be) aware of implementation used, so they can't call 
+        * 
org.ops4j.pax.web.service.WebContainer.createDefaultSharedHttpContext() 
+        * if they want to use shared context. <br/>
+        * Therefore we provide a configuration parameter that controls the 
behavior of publicly available
+        * method createDefaultHttpContext(). <br/>
+        * If the parameter is not set, or is set to false, the per-bundle 
HttpContext is returned, as
+        * in pre-6.1.0 versions. When it is set to true, the shared instance 
is returned.
+        * 
+        * @return true if should use shared HttpContext by default.
+        */
+       Boolean isUseSharedHttpContextByDefault();
 
        String getWorkerName();
 
diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
index e684627..47954a4 100644
--- 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
+++ 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/model/package-info.java
@@ -14,7 +14,7 @@
 limitations under the License.
  */
 
-@Version("6.0.0")
+@Version("6.1.0")
 package org.ops4j.pax.web.service.spi.model;
 
 import org.osgi.annotation.versioning.Version;
diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/package-info.java 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/package-info.java
index 9bfc86d..3c6e157 100644
--- a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/package-info.java
+++ b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/package-info.java
@@ -14,7 +14,7 @@
 limitations under the License.
  */
 
-@Version("6.0.0")
+@Version("6.1.0")
 package org.ops4j.pax.web.service.spi;
 
 import org.osgi.annotation.versioning.Version;
diff --git 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
index aabdd42..3df93db 100644
--- 
a/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
+++ 
b/pax-web-spi/src/main/java/org/ops4j/pax/web/service/spi/util/package-info.java
@@ -14,7 +14,7 @@
 limitations under the License.
  */
 
-@Version("6.0.0")
+@Version("6.1.0")
 package org.ops4j.pax.web.service.spi.util;
 
 import org.osgi.annotation.versioning.Version;

Reply via email to