You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by di...@apache.org on 2007/01/29 09:07:36 UTC

svn commit: r500959 - in /geronimo/server/trunk: ./ configs/cxf-deployer/ modules/geronimo-cxf-builder/ modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/ testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/...

Author: dims
Date: Mon Jan 29 00:07:35 2007
New Revision: 500959

URL: http://svn.apache.org/viewvc?view=rev&rev=500959
Log:
Fix for GERONIMO-2783 - CXF-based WebServices support: webservices.xml file is no longer required

Modified:
    geronimo/server/trunk/configs/cxf-deployer/pom.xml
    geronimo/server/trunk/modules/geronimo-cxf-builder/pom.xml
    geronimo/server/trunk/modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/CXFBuilder.java
    geronimo/server/trunk/pom.xml
    geronimo/server/trunk/testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/apache/hello_world_soap_http/handlers.xml

Modified: geronimo/server/trunk/configs/cxf-deployer/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/configs/cxf-deployer/pom.xml?view=diff&rev=500959&r1=500958&r2=500959
==============================================================================
--- geronimo/server/trunk/configs/cxf-deployer/pom.xml (original)
+++ geronimo/server/trunk/configs/cxf-deployer/pom.xml Mon Jan 29 00:07:35 2007
@@ -47,11 +47,18 @@
             <artifactId>geronimo-cxf-builder</artifactId>
             <version>${version}</version>
         </dependency>
+
         <dependency>
             <groupId>org.apache.geronimo.configs</groupId>
             <artifactId>cxf</artifactId>
             <type>car</type>
             <version>${version}</version>
+            <scope>runtime</scope>
+       </dependency>
+
+       <dependency>
+            <groupId>org.apache.xbean</groupId>
+            <artifactId>xbean-finder</artifactId>
             <scope>runtime</scope>
        </dependency>
 

Modified: geronimo/server/trunk/modules/geronimo-cxf-builder/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-cxf-builder/pom.xml?view=diff&rev=500959&r1=500958&r2=500959
==============================================================================
--- geronimo/server/trunk/modules/geronimo-cxf-builder/pom.xml (original)
+++ geronimo/server/trunk/modules/geronimo-cxf-builder/pom.xml Mon Jan 29 00:07:35 2007
@@ -55,16 +55,19 @@
         <dependency>
             <groupId>org.apache.geronimo.modules</groupId>
             <artifactId>geronimo-cxf</artifactId>
-            <version>${version}</version>                                                                                                           
+            <version>${version}</version>
         </dependency>
 
-        <!-- this is a dependency of geronimo-cxf.  Why isn't it picked up? -->
-        <dependency>
-            <groupId>org.apache.cxf</groupId>
-            <artifactId>cxf-rt-frontend-jaxws</artifactId>
-        </dependency>
+       <dependency>
+            <groupId>org.apache.xbean</groupId>
+            <artifactId>xbean-finder</artifactId>
+       </dependency>
+
+       <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-ws-metadata_2.0_spec</artifactId>
+       </dependency>
 
     </dependencies>
 
 </project>
-

Modified: geronimo/server/trunk/modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/CXFBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/CXFBuilder.java?view=diff&rev=500959&r1=500958&r2=500959
==============================================================================
--- geronimo/server/trunk/modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/CXFBuilder.java (original)
+++ geronimo/server/trunk/modules/geronimo-cxf-builder/src/main/java/org/apache/geronimo/cxf/builder/CXFBuilder.java Mon Jan 29 00:07:35 2007
@@ -16,22 +16,29 @@
  */
 package org.apache.geronimo.cxf.builder;
 
-
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.FileNotFoundException;
+import java.lang.reflect.Modifier;
 import java.net.URL;
 import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Collections;
+import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
+import javax.jws.WebService;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.WebServiceProvider;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -53,50 +60,170 @@
 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
 import org.apache.geronimo.cxf.PortInfo;
 import org.apache.geronimo.cxf.CXFWebServiceContainerFactoryGBean;
+import org.apache.geronimo.kernel.classloader.JarFileClassLoader;
 import org.apache.geronimo.kernel.repository.Environment;
 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
 import org.apache.geronimo.kernel.GBeanNotFoundException;
 import org.apache.geronimo.deployment.DeploymentContext;
 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
 import org.apache.geronimo.deployment.util.DeploymentUtil;
+import org.apache.xbean.finder.ClassFinder;
 
 public class CXFBuilder implements WebServiceBuilder {
 
     private static final Log LOG = LogFactory.getLog(CXFBuilder.class);
-    
+
     private final Environment defaultEnvironment;
+
     private static final String KEY = CXFBuilder.class.getName();
 
     public CXFBuilder(Environment defaultEnvironment) {
         this.defaultEnvironment = defaultEnvironment;
     }
 
-    public void findWebServices(JarFile moduleFile, boolean isEJB, Map servletLocations, Environment environment, Map sharedContext) throws DeploymentException {
-        final String path = isEJB ? "META-INF/webservices.xml" : "WEB-INF/webservices.xml";
+    public void findWebServices(JarFile moduleFile,
+                                boolean isEJB,
+                                Map servletLocations,
+                                Environment environment,
+                                Map sharedContext) throws DeploymentException {
+        Map portMap = null;
+        String path = isEJB ? "META-INF/webservices.xml" : "WEB-INF/webservices.xml";
         try {
             URL wsDDUrl = DeploymentUtil.createJarURL(moduleFile, path);
-            Map portMap = parseWebServiceDescriptor(wsDDUrl, moduleFile, isEJB, servletLocations);
-            if (portMap != null) {
-                EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
-                sharedContext.put(KEY, portMap);
+            InputStream in = wsDDUrl.openStream();
+            portMap = parseWebServiceDescriptor(in, wsDDUrl, moduleFile, isEJB, servletLocations);
+        } catch (IOException e) {
+            // webservices.xml does not exist, search classes for annotations
+            portMap = discoverWebServices(moduleFile, isEJB, servletLocations);
+        }
+
+        if (portMap != null) {
+            EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
+            sharedContext.put(KEY, portMap);
+        }
+
+    }
+
+    private Map<String, PortInfo> discoverWebServices(JarFile moduleFile,
+                                                      boolean isEJB,
+                                                      Map correctedPortLocations)
+            throws DeploymentException {
+        LOG.debug("Discovering web service classes");
+
+        File tmpDir = null;
+        List<URL> urlList = new ArrayList<URL>();
+        if (isEJB) {
+            File jarFile = new File(moduleFile.getName());
+            try {
+                urlList.add(jarFile.toURL());
+            } catch (MalformedURLException e) {
+                // this should not happen
+                throw new DeploymentException();
+            }
+        } else {
+            /*
+             * Can't get ClassLoader to load nested Jar files, so
+             * unpack the module Jar file and discover all nested Jar files
+             * within it and the classes/ directory.
+             */
+            try {
+                tmpDir = DeploymentUtil.createTempDir();
+                /*
+                 * This is needed becuase DeploymentUtil.unzipToDirectory() 
+                 * always closes the passed JarFile.
+                 */
+                JarFile module = new JarFile(moduleFile.getName());
+                DeploymentUtil.unzipToDirectory(module, tmpDir);
+            } catch (IOException e) {
+                if (tmpDir != null) {
+                    DeploymentUtil.recursiveDelete(tmpDir);
+                }
+                throw new DeploymentException("Failed to expand the module archive", e);
+            }
+            
+            // create URL list 
+            Enumeration<JarEntry> jarEnum = moduleFile.entries();
+            while (jarEnum.hasMoreElements()) {
+                JarEntry entry = jarEnum.nextElement();
+                String name = entry.getName();
+                if (name.equals("WEB-INF/classes/")) {
+                    // ensure it is first
+                    File classesDir = new File(tmpDir, "WEB-INF/classes/");
+                    try {
+                        urlList.add(0, classesDir.toURL());
+                    } catch (MalformedURLException e) {
+                        // this should not happen, ignore
+                    }
+                } else if (name.startsWith("WEB-INF/lib/")
+                        && name.endsWith(".jar")) {
+                    File jarFile = new File(tmpDir, name);                    
+                    try {
+                        urlList.add(jarFile.toURL());
+                    } catch (MalformedURLException e) {
+                        // this should not happen, ignore
+                    }
+                }
+            }               
+        }
+
+        URL[] urls = urlList.toArray(new URL[] {});
+        JarFileClassLoader tempClassLoader = new JarFileClassLoader(null, urls, this.getClass().getClassLoader());       
+        ClassFinder classFinder = new ClassFinder(tempClassLoader, urlList);
+
+        Map<String, PortInfo> map = null;
+        List<Class> classes = null;
+        
+        classes = classFinder.findAnnotatedClasses(WebService.class);        
+        map = updatePortMap(classes, map, correctedPortLocations);
+        classes = classFinder.findAnnotatedClasses(WebServiceProvider.class);
+        map = updatePortMap(classes, map, correctedPortLocations);
+               
+        tempClassLoader.destroy();
+        
+        if (tmpDir != null) {
+            DeploymentUtil.recursiveDelete(tmpDir);
+        }
+        
+        return map;
+    }
+
+    private static Map<String, PortInfo> updatePortMap(List<Class> classes,
+                                                       Map<String, PortInfo> map,
+                                                       Map correctedPortLocations) {
+        for (Class clazz : classes) {
+            if (isProperWebService(clazz)) {
+                LOG.debug("Found web service class: " + clazz.getName());
+                if (map == null) {
+                    map = new HashMap<String, PortInfo>();
+                }
+                PortInfo portInfo = new PortInfo();
+                String location = (String) correctedPortLocations.get(clazz.getName());
+                portInfo.setLocation(location);
+                map.put(clazz.getName(), portInfo);
             }
-        } catch (MalformedURLException e) {
-            // The webservices.xml file doesn't exist.
         }
+        return map;
+    }
+
+    private static boolean isProperWebService(Class clazz) {
+        int modifiers = clazz.getModifiers();
+        return (Modifier.isPublic(modifiers) && 
+                !Modifier.isFinal(modifiers) && 
+                !Modifier.isAbstract(modifiers));
     }
-    
-    private Map<String, PortInfo> parseWebServiceDescriptor(URL wsDDUrl, JarFile moduleFile, boolean isEJB, Map correctedPortLocations) throws DeploymentException {
+
+    private Map<String, PortInfo> parseWebServiceDescriptor(InputStream in,
+                                                            URL wsDDUrl,
+                                                            JarFile moduleFile,
+                                                            boolean isEJB,
+                                                            Map correctedPortLocations)
+            throws DeploymentException {
 
         LOG.debug("Parsing descriptor " + wsDDUrl);
 
-        Map<String, PortInfo> map = new HashMap<String, PortInfo>();
+        Map<String, PortInfo> map = null;
 
         try {
-            InputStream in = wsDDUrl.openStream();
-            if (in == null) {
-                throw new DeploymentException("unable to read descriptor " + wsDDUrl);
-            }
-
             JAXBContext ctx = JAXBContext.newInstance(WebservicesType.class);
             Unmarshaller unmarshaller = ctx.createUnmarshaller();
             Object obj = unmarshaller.unmarshal(new StreamSource(in), WebservicesType.class);
@@ -111,17 +238,17 @@
             WebservicesType wst = (WebservicesType) obj;
 
             for (WebserviceDescriptionType desc : wst.getWebserviceDescription()) {
-                String wsdlFile = null;                
+                String wsdlFile = null;
                 if (desc.getWsdlFile() != null) {
                     wsdlFile = getString(desc.getWsdlFile().getValue());
                 }
-                
+
                 String serviceName = desc.getWebserviceDescriptionName().getValue();
 
                 for (PortComponentType port : desc.getPortComponent()) {
-                    
+
                     PortInfo portInfo = new PortInfo();
-                                       
+
                     String serviceLink = null;
                     ServiceImplBeanType beanType = port.getServiceImplBean();
                     if (beanType.getEjbLink() != null) {
@@ -130,36 +257,39 @@
                         serviceLink = beanType.getServletLink().getValue();
                     }
                     portInfo.setServiceLink(serviceLink);
-                                        
+
                     if (port.getServiceEndpointInterface() != null) {
                         String sei = port.getServiceEndpointInterface().getValue();
                         portInfo.setServiceEndpointInterfaceName(sei);
                     }
-                                        
+
                     String portName = port.getPortComponentName().getValue();
                     portInfo.setPortName(portName);
-                    
-                    portInfo.setProtocolBinding(port.getProtocolBinding());                    
-                    portInfo.setServiceName(serviceName);      
-                    portInfo.setWsdlFile(wsdlFile);                    
-                    
+
+                    portInfo.setProtocolBinding(port.getProtocolBinding());
+                    portInfo.setServiceName(serviceName);
+                    portInfo.setWsdlFile(wsdlFile);
+
                     if (port.getEnableMtom() != null) {
                         portInfo.setEnableMTOM(port.getEnableMtom().isValue());
-                    }                    
-                                                                        
+                    }
+
                     portInfo.setHandlers(port.getHandlerChains());
-                    
+
                     if (port.getWsdlPort() != null) {
                         portInfo.setWsdlPort(port.getWsdlPort().getValue());
                     }
-                    
+
                     if (port.getWsdlService() != null) {
                         portInfo.setWsdlService(port.getWsdlService().getValue());
                     }
-                                                    
+
                     String location = (String)correctedPortLocations.get(serviceLink);
                     portInfo.setLocation(location);
-                    
+
+                    if (map == null) {
+                        map = new HashMap<String, PortInfo>();
+                    }
                     map.put(serviceLink, portInfo);
                 }
             }
@@ -168,36 +298,51 @@
         } catch (FileNotFoundException e) {
             return Collections.EMPTY_MAP;
         } catch (IOException ex) {
-            throw new DeploymentException("unable to read " + wsDDUrl, ex);
+            throw new DeploymentException("Unable to read " + wsDDUrl, ex);
         } catch (JAXBException ex) {
-            throw new DeploymentException("unable to parse webservices.xml", ex);
+            throw new DeploymentException("Unable to parse " + wsDDUrl, ex);
         } catch (Exception ex) {
             throw new DeploymentException("Unknown deployment error", ex);
+        } finally {
+            try {
+                in.close();
+            } catch (IOException e) {
+                // ignore
+            }
         }
     }
-    
+
     private static String getString(String in) {
         if (in != null) {
             in = in.trim();
             if (in.length() == 0) {
                 return null;
-            }            
+            }
         }
         return in;
     }
 
-    public boolean configurePOJO(GBeanData targetGBean, String servletName, Module module, String seiClassName, DeploymentContext context) throws DeploymentException {
+    public boolean configurePOJO(GBeanData targetGBean,
+                                 String servletName,
+                                 Module module,
+                                 String seiClassName,
+                                 DeploymentContext context)
+            throws DeploymentException {
         Map sharedContext = ((WebModule) module).getSharedContext();
         Map portInfoMap = (Map) sharedContext.get(KEY);
+        if (portInfoMap == null) {
+            // not ours
+            return false;
+        }
         PortInfo portInfo = (PortInfo) portInfoMap.get(servletName);
         if (portInfo == null) {
-            //not ours
+            // not ours
             return false;
         }
 
         Map componentContext = null;
         try {
-            GBeanData moduleGBean = context.getGBeanInstance(context.getModuleName()); 
+            GBeanData moduleGBean = context.getGBeanInstance(context.getModuleName());
             componentContext = (Map)moduleGBean.getAttribute("componentContext");
         } catch (GBeanNotFoundException e) {
             LOG.warn("ModuleGBean not found. JNDI resource injection will not work.");
@@ -221,18 +366,23 @@
         }
 
         targetGBean.setReferencePattern("WebServiceContainerFactory", containerFactoryName);
-        // our web container does not use that property 
+        // our web container does not use that property
         targetGBean.setAttribute("pojoClassName", "java.lang.Object");
 
         if (context instanceof EARContext) {
-            containerFactoryData.setReferencePattern("TransactionManager", 
+            containerFactoryData.setReferencePattern("TransactionManager",
                                                      ((EARContext)context).getTransactionManagerName());
         }
 
         return true;
     }
 
-    public boolean configureEJB(GBeanData targetGBean, String ejbName, JarFile moduleFile, Map sharedContext, ClassLoader classLoader) throws DeploymentException {
+    public boolean configureEJB(GBeanData targetGBean,
+                                String ejbName,
+                                JarFile moduleFile,
+                                Map sharedContext,
+                                ClassLoader classLoader)
+            throws DeploymentException {
         throw new DeploymentException("configureEJB NYI");
     }
 

Modified: geronimo/server/trunk/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/pom.xml?view=diff&rev=500959&r1=500958&r2=500959
==============================================================================
--- geronimo/server/trunk/pom.xml (original)
+++ geronimo/server/trunk/pom.xml Mon Jan 29 00:07:35 2007
@@ -261,6 +261,12 @@
             </dependency>
 
             <dependency>
+                <groupId>org.apache.xbean</groupId>
+                <artifactId>xbean-finder</artifactId>
+                <version>2.8</version>
+            </dependency>
+
+            <dependency>
                 <groupId>jline</groupId>
                 <artifactId>jline</artifactId>
                 <version>0.9.9</version>

Modified: geronimo/server/trunk/testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/apache/hello_world_soap_http/handlers.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/apache/hello_world_soap_http/handlers.xml?view=diff&rev=500959&r1=500958&r2=500959
==============================================================================
--- geronimo/server/trunk/testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/apache/hello_world_soap_http/handlers.xml (original)
+++ geronimo/server/trunk/testsuite/webservices-testsuite/jaxws-tests/jaxws-war/src/main/java/org/apache/hello_world_soap_http/handlers.xml Mon Jan 29 00:07:35 2007
@@ -2,6 +2,7 @@
 <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
   <jws:handler-chain>
     <jws:handler>
+      <jws:handler-name>GreeterHandler</jws:handler-name>
       <jws:handler-class>org.apache.hello_world_soap_http.GreeterHandler</jws:handler-class>
     </jws:handler>
   </jws:handler-chain>