You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bi...@apache.org on 2008/03/25 20:09:07 UTC

svn commit: r640944 - in /incubator/cxf/trunk: benchmark/profiling/ distribution/ rt/core/ rt/core/src/main/java/org/apache/cxf/bus/spring/

Author: bimargulies
Date: Tue Mar 25 12:09:05 2008
New Revision: 640944

URL: http://svn.apache.org/viewvc?rev=640944&view=rev
Log:
Turn on the FI performance enhancement for Spring configuration jars.

Modified:
    incubator/cxf/trunk/benchmark/profiling/build.xml
    incubator/cxf/trunk/distribution/pom.xml
    incubator/cxf/trunk/rt/core/pom.xml
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java

Modified: incubator/cxf/trunk/benchmark/profiling/build.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/benchmark/profiling/build.xml?rev=640944&r1=640943&r2=640944&view=diff
==============================================================================
--- incubator/cxf/trunk/benchmark/profiling/build.xml (original)
+++ incubator/cxf/trunk/benchmark/profiling/build.xml Tue Mar 25 12:09:05 2008
@@ -170,10 +170,10 @@
     <java classname="org.apache.cxf.profile.DefaultBusInitialization" fork="true">
       <arg value="100"/>
       <arg value="bus_initialization.jps"/>
-      <jvmarg value="-Dcxf.config.file=bloop.xml"/>
 <!--
-      <jvmarg value="-Dorg.xml.sax.driver=com.ctc.wstx.sax.WstxSAXParser"/>
+      <jvmarg value="-Dorg.apache.cxf.nofastinfoset=true"/>
 -->
+      <jvmarg value="-Dcxf.config.file=bloop.xml"/>
       <jvmarg value="-agentlib:jprofilerti=offline,id=146,config=jprofileConfig.xml"></jvmarg>
       <jvmarg value="-Xbootclasspath/a:${jprofile.home}/bin/agent.jar"></jvmarg>
       <env key="LD_LIBRARY_PATH" path="${nativelib.dir}:${nativelib.envvarValue}"/>

Modified: incubator/cxf/trunk/distribution/pom.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/distribution/pom.xml?rev=640944&r1=640943&r2=640944&view=diff
==============================================================================
--- incubator/cxf/trunk/distribution/pom.xml (original)
+++ incubator/cxf/trunk/distribution/pom.xml Tue Mar 25 12:09:05 2008
@@ -314,7 +314,7 @@
                     </execution>
                     <execution>
                         <!-- copy additional jars. These are jars we want included, but don't 
-                                     really don't want tem on the classpath in the normal case -->
+                                     really don't want them on the classpath in the normal case -->
                         <id>add-jars</id>
                         <phase>package</phase>
                         <goals>

Modified: incubator/cxf/trunk/rt/core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/pom.xml?rev=640944&r1=640943&r2=640944&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/core/pom.xml (original)
+++ incubator/cxf/trunk/rt/core/pom.xml Tue Mar 25 12:09:05 2008
@@ -71,6 +71,13 @@
             <artifactId>easymockclassextension</artifactId>
             <scope>test</scope>
         </dependency>
+
+       <dependency>
+         <groupId>com.sun.xml.fastinfoset</groupId>
+         <artifactId>FastInfoset</artifactId>
+         <version>1.2.2</version>
+        </dependency>
+
     </dependencies>
 
 

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java?rev=640944&r1=640943&r2=640944&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/ControlledValidationXmlBeanDefinitionReader.java Tue Mar 25 12:09:05 2008
@@ -21,6 +21,12 @@
 
 import java.io.IOException;
 import java.net.URL;
+import java.net.URLConnection;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
 
 import org.xml.sax.InputSource;
 
@@ -28,23 +34,55 @@
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
 import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.support.EncodedResource;
 
 /**
- * This is a mutant version of the bean definition reader
- * which allows us to avoid validating our internal CXF
- * configuration files.
+ * CXF reads a series of Spring XML files as part of initialization.
+ * The time it takes to parse them, especially if validating, builds up.
+ * The XML files shipped in a release in the JARs are valid and invariant.
+ * To speed things up, this class implements two levels of optimization.
+ * When a CXF distribution is fully-packaged, each of the Spring XML 
+ * bus extension .xml files is accompanied by a FastInfoset '.fixml' file.
+ * These read much more rapidly. When one of those is present, this classs
+ * reads it instead of reading the XML text file. 
+ * 
+ * Absent a .fixml file, this class uses WoodStox instead of Xerces (or
+ * whatever the JDK is providing).
+ * 
+ * The Woodstox optimization also applies to user cxf.xml or cxf-servlet.xml files
+ * if the user has disabled XML validation of Spring files with
+ * the org.apache.cxf.spring.validation.mode system property.
+ * 
+ * Note that the fastInfoset optimization is only applied for the 
+ * methods here that start from a Resource. If this is called with an InputSource,
+ * that optimization is not applied, since we can't reliably know the
+ * location of the XML. 
  */
 public class ControlledValidationXmlBeanDefinitionReader extends XmlBeanDefinitionReader {
 
-    // Spring has no 'getter' for this.
-    private int visibleValidationMode = VALIDATION_AUTO;
+    /**
+     * Exception class used to avoid reading old FastInfoset files.
+     */
+    private static class StaleFastinfosetException extends Exception {
+
+    }
 
+    // the following flag allows performance comparisons with and 
+    // without fast infoset processing.
+    private boolean noFastinfoset;
+    // Spring has no 'getter' for this, so we need our own copy.
+    private int visibleValidationMode = VALIDATION_AUTO;
+    // We need a reference to the subclass.
+    private TunedDocumentLoader tunedDocumentLoader;
     /**
      * @param beanFactory
      */
     public ControlledValidationXmlBeanDefinitionReader(BeanDefinitionRegistry beanFactory) {
         super(beanFactory);
-        this.setDocumentLoader(new TunedDocumentLoader());
+        tunedDocumentLoader = new TunedDocumentLoader();
+        this.setDocumentLoader(tunedDocumentLoader);
+        noFastinfoset = System.getProperty("org.apache.cxf.nofastinfoset") != null;
     }
 
     @Override
@@ -76,6 +114,54 @@
     public void setValidationMode(int validationMode) {
         visibleValidationMode = validationMode;
         super.setValidationMode(validationMode);
+    }
+
+    @Override
+    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
+        if (noFastinfoset) {
+            return super.loadBeanDefinitions(encodedResource);
+        }
+
+        try {
+            return fastInfosetLoadBeanDefinitions(encodedResource);
+        } catch (Exception e) {
+            return super.loadBeanDefinitions(encodedResource);
+        }
+    }
+    
+    private int fastInfosetLoadBeanDefinitions(EncodedResource encodedResource)
+        throws TransformerConfigurationException, IOException,
+        TransformerException, StaleFastinfosetException {
+        URL resUrl = encodedResource.getResource().getURL();
+        // There are XML files scampering around that don't end in .xml.
+        // We don't apply the optimization to them.
+        if (!resUrl.getPath().endsWith(".xml")) {
+            throw new StaleFastinfosetException();
+        }
+        String fixmlPath = resUrl.getPath().replaceFirst("\\.xml$", ".fixml");
+        String protocol = resUrl.getProtocol();
+        // beware of the relative URL rules for jar:, which are surprising.
+        if ("jar".equals(protocol)) {
+            fixmlPath = fixmlPath.replaceFirst("^.*!", "");
+        }
+        
+        URL fixmlUrl = new URL(resUrl, fixmlPath);
+
+        // if we are in unpacked files, we take some extra time
+        // to ensure that we aren't using a stale Fastinfoset file.
+        if (protocol.equals("file")) {
+            URLConnection resCon = null;
+            URLConnection fixCon = null;
+            resCon = resUrl.openConnection();
+            fixCon = fixmlUrl.openConnection();
+            if (resCon.getLastModified() > fixCon.getLastModified()) {
+                throw new StaleFastinfosetException();
+            }
+        }
+        
+        Resource newResource = new UrlResource(fixmlUrl); 
+        Document doc = tunedDocumentLoader.loadFastinfosetDocument(fixmlUrl);
+        return registerBeanDefinitions(doc, newResource);
     }
 
 }

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java?rev=640944&r1=640943&r2=640944&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/TunedDocumentLoader.java Tue Mar 25 12:09:05 2008
@@ -19,10 +19,17 @@
 
 package org.apache.cxf.bus.spring;
 
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.sax.SAXSource;
@@ -35,6 +42,7 @@
 import org.xml.sax.XMLReader;
 
 import com.ctc.wstx.sax.WstxSAXParserFactory;
+import com.sun.xml.fastinfoset.sax.SAXDocumentParser;
 
 import org.springframework.beans.factory.xml.DefaultDocumentLoader;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
@@ -45,7 +53,8 @@
 class TunedDocumentLoader extends DefaultDocumentLoader {
     
     // DocumentBuilderFactories are somewhat expensive but not thread-safe.
-    // We only use this builder with WoodStox, we respect Spring's desire to make new factories 
+    // We only use this builder with WoodStox, and Fast Infoset 
+    // and we respect Spring's desire to make new factories 
     // when we aren't doing the optimization.
     private static DocumentBuilder documentBuilder;
     static {
@@ -67,6 +76,7 @@
                                  ErrorHandler errorHandler, int validationMode, boolean namespaceAware)
         throws Exception {
         if (validationMode == XmlBeanDefinitionReader.VALIDATION_NONE) {
+            
             WstxSAXParserFactory woodstoxParserFactory;
             woodstoxParserFactory = new WstxSAXParserFactory();
             woodstoxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", 
@@ -100,6 +110,20 @@
             // blank
         }
         return factory;
+    }
+    
+    Document loadFastinfosetDocument(URL url) 
+        throws IOException, TransformerConfigurationException, TransformerException {
+        InputStream is = url.openStream();
+        XMLReader saxReader = new SAXDocumentParser();
+        InputStream in = new BufferedInputStream(is);
+        SAXSource saxSource = new SAXSource(saxReader, new InputSource(in));
+        Document document;
+        document = documentBuilder.newDocument();
+        DOMResult domResult = new DOMResult(document);
+        transformerFactory.newTransformer().transform(saxSource, domResult);
+        is.close();
+        return document;
     }
 
 }