This is an automated email from the ASF dual-hosted git repository.

jerrick pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 393ffce  prototype for issue2570 (#2640)
393ffce is described below

commit 393ffce5df5ac94a209914623d9a10bf94ef3b13
Author: Ian Luo <ian....@gmail.com>
AuthorDate: Tue Oct 16 16:16:54 2018 +0800

    prototype for issue2570 (#2640)
    
    * #2570: dubbo all in one fail to start from a tomcat server when spring 
framework is absent
    
    * add comments and fix unit test
    
    * add license header
    
    * update comments in unit tests
---
 .../spring/initializer/DubboContextListener.java   | 72 ++++++++++++++++++++++
 .../src/main/resources/META-INF/web-fragment.xml   |  4 +-
 .../DubboApplicationContextInitializerTest.java    |  9 +--
 .../spring/status/DataSourceStatusCheckerTest.java |  2 +-
 4 files changed, 80 insertions(+), 7 deletions(-)

diff --git 
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboContextListener.java
 
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboContextListener.java
new file mode 100644
index 0000000..35b2b70
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/initializer/DubboContextListener.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.dubbo.config.spring.initializer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * A Dubbo context listener is a delegation to 
org.springframework.web.context.ContextLoaderListener. This is necessary,
+ * because Dubbo is packaged into all-in-one jar, therefore it contains a 
web-fragment.xml from this sub module which's
+ * used for helping to assemble spring context listener automatically when 
it's not configured explicitly by user in
+ * web.xml. It works fine with spring, but it will lead to ClassNotFound 
exception and fail tomcat's bootup when user
+ * doesn't depend on spring framework.
+ */
+public class DubboContextListener implements ServletContextListener {
+    private static final Log logger = 
LogFactory.getLog(DubboContextListener.class);
+
+    private static final String SPRING_CONTEXT_LISTENER = 
"org.springframework.web.context.ContextLoaderListener";
+    private static final String SPRING_CONTEXT_ROOT = 
"org.springframework.web.context.WebApplicationContext.ROOT";
+
+    private ServletContextListener springContextListener;
+    private boolean executed = false;
+
+    public DubboContextListener() {
+        try {
+            Class c = Class.forName(SPRING_CONTEXT_LISTENER);
+            springContextListener = (ServletContextListener) c.newInstance();
+        } catch (ClassNotFoundException | IllegalAccessException | 
InstantiationException e) {
+            logger.warn("Servlet container detects dubbo's web fragment 
configuration, and tries to load " +
+                    "org.springframework.web.context.ContextLoaderListener but 
fails to find the class. " +
+                    "If the application don't rely on Spring framework, pls. 
simply ignore");
+        }
+    }
+
+    @Override
+    public void contextInitialized(ServletContextEvent servletContextEvent) {
+        if (springContextListener != null) {
+            // if spring context listener has already been registered, then do 
nothing
+            ServletContext context = servletContextEvent.getServletContext();
+            if (context.getAttribute(SPRING_CONTEXT_ROOT) == null) {
+                executed = true;
+                springContextListener.contextInitialized(servletContextEvent);
+            }
+        }
+    }
+
+    @Override
+    public void contextDestroyed(ServletContextEvent servletContextEvent) {
+        if (springContextListener != null && executed) {
+            springContextListener.contextDestroyed(servletContextEvent);
+        }
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml 
b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml
index c063bdf..e1eef6b 100644
--- 
a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml
+++ 
b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/web-fragment.xml
@@ -16,7 +16,7 @@
     </context-param>
 
     <listener>
-        
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+        
<listener-class>org.apache.dubbo.config.spring.initializer.DubboContextListener</listener-class>
     </listener>
 
-</web-fragment>
\ No newline at end of file
+</web-fragment>
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java
index b5b8f8c..02dda03 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationContextInitializerTest.java
@@ -38,8 +38,9 @@ public class DubboApplicationContextInitializerTest {
         context.addLifecycleListener(new ContextConfig());
         tomcat.getHost().addChild(context);
         tomcat.start();
-        // there should be 1 application listener
-        Assert.assertEquals(1, 
context.getApplicationLifecycleListeners().length);
+        // there should be 2 application listeners, one is spring context 
listener,
+        // the other is its wrapper dubbo introduces.
+        Assert.assertEquals(2, 
context.getApplicationLifecycleListeners().length);
         // the first one should be Spring's built in ContextLoaderListener.
         Assert.assertTrue(context.getApplicationLifecycleListeners()[0] 
instanceof ContextLoaderListener);
         tomcat.stop();
@@ -58,10 +59,10 @@ public class DubboApplicationContextInitializerTest {
         context.addLifecycleListener(new ContextConfig());
         tomcat.getHost().addChild(context);
         tomcat.start();
-        // there should be 1 application listener
+        // there should be 1 application listener, which is spring context 
listener's wrapper introduced by dubbo
         Assert.assertEquals(1, 
context.getApplicationLifecycleListeners().length);
         // the first one should be Spring's built in ContextLoaderListener.
-        Assert.assertTrue(context.getApplicationLifecycleListeners()[0] 
instanceof ContextLoaderListener);
+        Assert.assertTrue(context.getApplicationLifecycleListeners()[0] 
instanceof DubboContextListener);
         tomcat.stop();
         tomcat.destroy();
     }
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/status/DataSourceStatusCheckerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/status/DataSourceStatusCheckerTest.java
index 532d97b..c82fd4a 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/status/DataSourceStatusCheckerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/status/DataSourceStatusCheckerTest.java
@@ -49,6 +49,7 @@ public class DataSourceStatusCheckerTest {
 
     @Before
     public void setUp() throws Exception {
+        SpringExtensionFactory.clearContexts();
         initMocks(this);
         this.dataSourceStatusChecker = new DataSourceStatusChecker();
         new ServiceBean<Object>().setApplicationContext(applicationContext);
@@ -56,7 +57,6 @@ public class DataSourceStatusCheckerTest {
 
     @After
     public void tearDown() throws Exception {
-        SpringExtensionFactory.clearContexts();
         Mockito.reset(applicationContext);
     }
 

Reply via email to