[jboss-cvs] JBossAS SVN: r104320 - in projects/ejb3/components/embedded/trunk: impl-base and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Apr 29 12:27:10 EDT 2010


Author: ALRubinger
Date: 2010-04-29 12:27:08 -0400 (Thu, 29 Apr 2010)
New Revision: 104320

Added:
   projects/ejb3/components/embedded/trunk/impl-base/src/test/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/
   projects/ejb3/components/embedded/trunk/impl-base/src/test/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilterUnitTest.java
Modified:
   projects/ejb3/components/embedded/trunk/build/pom.xml
   projects/ejb3/components/embedded/trunk/impl-base/pom.xml
   projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/ClassPathEjbJarScanner.java
   projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilter.java
   projects/ejb3/components/embedded/trunk/spi/src/main/java/org/jboss/ejb3/embedded/spi/scanner/filter/ExclusionFilter.java
Log:
[EJBTHREE-2083] Add a BundleSymbolicNameExclusionFilter and tests

Modified: projects/ejb3/components/embedded/trunk/build/pom.xml
===================================================================
--- projects/ejb3/components/embedded/trunk/build/pom.xml	2010-04-29 15:11:25 UTC (rev 104319)
+++ projects/ejb3/components/embedded/trunk/build/pom.xml	2010-04-29 16:27:08 UTC (rev 104320)
@@ -179,6 +179,11 @@
         <artifactId>shrinkwrap-impl-base</artifactId>
         <version>${version.org.jboss.shrinkwrap}</version>
       </dependency>
+      <dependency>
+        <groupId>org.jboss.shrinkwrap</groupId>
+        <artifactId>shrinkwrap-extension-vfs3</artifactId>
+        <version>${version.org.jboss.shrinkwrap}</version>
+      </dependency>
 
     </dependencies>
   </dependencyManagement>

Modified: projects/ejb3/components/embedded/trunk/impl-base/pom.xml
===================================================================
--- projects/ejb3/components/embedded/trunk/impl-base/pom.xml	2010-04-29 15:11:25 UTC (rev 104319)
+++ projects/ejb3/components/embedded/trunk/impl-base/pom.xml	2010-04-29 16:27:08 UTC (rev 104320)
@@ -65,6 +65,11 @@
       <artifactId>shrinkwrap-impl-base</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.jboss.shrinkwrap</groupId>
+      <artifactId>shrinkwrap-extension-vfs3</artifactId>
+      <scope>test</scope>
+    </dependency>
     
   </dependencies>
 </project>

Modified: projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/ClassPathEjbJarScanner.java
===================================================================
--- projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/ClassPathEjbJarScanner.java	2010-04-29 15:11:25 UTC (rev 104319)
+++ projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/ClassPathEjbJarScanner.java	2010-04-29 16:27:08 UTC (rev 104320)
@@ -28,6 +28,7 @@
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -36,6 +37,8 @@
 import javax.ejb.Stateful;
 import javax.ejb.Stateless;
 
+import org.jboss.ejb3.embedded.impl.base.scanner.filter.BundleSymbolicNameExclusionFilter;
+import org.jboss.ejb3.embedded.spi.scanner.filter.ExclusionFilter;
 import org.jboss.logging.Logger;
 import org.jboss.vfs.TempFileProvider;
 import org.jboss.vfs.VFS;
@@ -56,16 +59,14 @@
    /*
     * This is an intentionally naive implementation which essentially
     * amounts to junkware.  It gets us to the next phases of development, 
-    * but isn't intended to be the final solution.
+    * but isn't intended to be the final solution.  For starters it's a static utility.
     * 
     * Open issues:
     * 
     * 1) Don't load all Classes to look for annotations.  Vie for ASM or Javassist (or 
     * other bytecode analyzer).  Or pass through an isolated VDF Deployer chain and let the
     * deployers figure out what the eligible modules are
-    * 2) Extract out a configurable set of ExclusionFilters which can determine if a given 
-    * root should be skipped (ie. for JUnit or JBossAS binaries)
-    * 3) Define a configurable ScheduledExecutorService to back the TempFileProvider
+    * 2) Define a configurable ScheduledExecutorService to back the TempFileProvider
     * used to mount ZIP VFS roots.  If we go the deployer chain route as noted by 1) this 
     * won't be necessary 
     */
@@ -121,6 +122,17 @@
    private static final ScheduledExecutorService ses = Executors.newScheduledThreadPool(Runtime.getRuntime()
          .availableProcessors());
 
+   /**
+    * Configured exclusion filters
+    * TODO Shouldn't be hardcoded, but available via user configuration
+    */
+   private static final List<ExclusionFilter> exclusionFilters;
+   static
+   {
+      exclusionFilters = new ArrayList<ExclusionFilter>();
+      exclusionFilters.add(new BundleSymbolicNameExclusionFilter("org.eclipse", "org.junit"));
+   }
+
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
@@ -206,6 +218,7 @@
          // If the file exists
          if (file.exists())
          {
+
             // Mount Exploded dir
             if (file.isDirectory())
             {
@@ -223,8 +236,11 @@
             // No conditions met
             else
             {
+               // So it's obvious if we've got something we didn't properly mount
+               log.warn("Encountered unknown file type, skipping: " + file);
                return false;
             }
+
          }
          // Not a real file
          else
@@ -233,14 +249,23 @@
             return false;
          }
 
-      }
-      catch (final IOException e)
-      {
-         throw new RuntimeException("Could not mount file from ClassPath for EJB JAR module scanning", e);
-      }
+         /*
+          * See if we've been configured to skip this file
+          */
+         for (final ExclusionFilter exclusionFilter : exclusionFilters)
+         {
+            // If we should exclude this
+            if (exclusionFilter.exclude(file))
+            {
+               // Exclude from further processing
+               if (log.isTraceEnabled())
+               {
+                  log.tracef("%s matched %s for exclusion; skipping", exclusionFilter, file);
+               }
+               return false;
+            }
+         }
 
-      try
-      {
          /*
           * Directories and real JARs are handled the same way in VFS, so just do
           * one check and skip logic to test isDirectory or not
@@ -265,7 +290,12 @@
 
          // Return
          return false;
+
       }
+      catch (final IOException e)
+      {
+         throw new RuntimeException("Could not mount file from ClassPath for EJB JAR module scanning", e);
+      }
       finally
       {
          try
@@ -278,6 +308,7 @@
             log.warn("Could not close handle to mounted " + file, e);
          }
       }
+
    }
 
    /**
@@ -330,7 +361,7 @@
             final String className = childName.substring(0, childName.length() - EXTENSION_CLASS.length()).replace('/',
                   '.');
 
-            // Here's the naughty part; loading the Class (which we really don't need to do, just inspect for annotations)
+            // Here's the naughty part; loading the Class (which we really don't need to do at all, just inspect for annotations)
             Class<?> clazz = null;
             try
             {
@@ -342,11 +373,10 @@
             }
             catch (final NoClassDefFoundError ncdfe)
             {
-               // Ugly ugly hack, Eclipse IDE JUnit runner puts stuff on the CP which can't be loaded
-               // This will be solved by a configurable exclusion filter so we don't look in the root
-               // in the first place.
-               log.warnf("Dev Hack Alert: Ignoring class on ClassPath which can't be loaded due to %s", ncdfe
-                     .toString());
+               // Ugly hack used to identify the stuff for which we need to configure an exclusion filter
+               log.warnf(
+                     "Dev Hack Alert: Ignoring class on ClassPath which can't be loaded due to %s while loading %s; "
+                           + "configure an exclusion filter so %s is not processed", ncdfe.toString(), className, root);
             }
 
             // Determine if we have a class with an EJB component annotation 

Modified: projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilter.java
===================================================================
--- projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilter.java	2010-04-29 15:11:25 UTC (rev 104319)
+++ projects/ejb3/components/embedded/trunk/impl-base/src/main/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilter.java	2010-04-29 16:27:08 UTC (rev 104320)
@@ -22,6 +22,9 @@
 
 package org.jboss.ejb3.embedded.impl.base.scanner.filter;
 
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -127,13 +130,42 @@
       }
 
       // Inspect the manifest contents
-      //TODO Left off here
+      final LineNumberReader reader;
+      try
+      {
+         reader = new LineNumberReader(new InputStreamReader(manifest.openStream()));
+         String line = null;
+         // Read each line
+         while ((line = reader.readLine()) != null)
+         {
+            // If this is the bundle symbolic name header
+            final String header = HEADER_BUNDLE_SYMBOLIC_NAME;
+            if (line.contains(header))
+            {
+               // Check if it also contains a matching value
+               for (final String exclusionValue : this.exclusionValues)
+               {
+                  if (line.contains(exclusionValue))
+                  {
+                     if (log.isTraceEnabled())
+                     {
+                        log.tracef("Configured exclusion value \"" + exclusionValue
+                              + "\" encountered in manifest header \"" + header + "\"; skipping " + file);
+                     }
+                     // Skip
+                     return true;
+                  }
+               }
+            }
+         }
+      }
+      catch (final IOException ioe)
+      {
+         throw new RuntimeException("Could not read contents of " + file, ioe);
+      }
 
       // No conditions met
       return false;
    }
 
-   //-------------------------------------------------------------------------------------||
-   // Internal Helper Methods ------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
 }

Added: projects/ejb3/components/embedded/trunk/impl-base/src/test/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilterUnitTest.java
===================================================================
--- projects/ejb3/components/embedded/trunk/impl-base/src/test/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilterUnitTest.java	                        (rev 0)
+++ projects/ejb3/components/embedded/trunk/impl-base/src/test/java/org/jboss/ejb3/embedded/impl/base/scanner/filter/BundleSymbolicNameExclusionFilterUnitTest.java	2010-04-29 16:27:08 UTC (rev 104320)
@@ -0,0 +1,198 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.embedded.impl.base.scanner.filter;
+
+import java.io.ByteArrayInputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.jboss.ejb3.embedded.spi.scanner.filter.ExclusionFilter;
+import org.jboss.logging.Logger;
+import org.jboss.shrinkwrap.api.Asset;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.vfs3.ArchiveFileSystem;
+import org.jboss.vfs.TempFileProvider;
+import org.jboss.vfs.VFS;
+import org.jboss.vfs.VirtualFile;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests that the {@link BundleSymbolicNameExclusionFilter}
+ * is working as expected
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class BundleSymbolicNameExclusionFilterUnitTest
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(BundleSymbolicNameExclusionFilterUnitTest.class);
+
+   /**
+    * Service backing the temp file provider
+    */
+   private static ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
+
+   /**
+    * Temp file provider backing mounted Archives
+    */
+   private static TempFileProvider provider = null;
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Handles to close when done
+    */
+   private final Set<Closeable> handles = new HashSet<Closeable>();
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Sets up the temporary file provider
+    */
+   @BeforeClass
+   public static void createTempFileProvider() throws IOException
+   {
+      provider = TempFileProvider.create("shrinkwrap-", service);
+   }
+
+   /**
+    * Shuts down the service
+    */
+   @AfterClass
+   public static void shutdownService()
+   {
+      service.shutdownNow();
+   }
+
+   /**
+    * Closes all handles from the mounting process
+    * @throws IOException
+    */
+   @After
+   public void closeHandles()
+   {
+      for (final Closeable handle : handles)
+      {
+         try
+         {
+            handle.close();
+         }
+         catch (final IOException ioe)
+         {
+            // Ignore
+         }
+      }
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that a JAR with a manifest header of 
+    * "Bundle-SymbolicName" matching a given pattern is excluded
+    */
+   @Test
+   public void honorsExclusion() throws IOException
+   {
+      final String bundleValue = "org.jboss.test";
+      final boolean excluded = this.filter(bundleValue, bundleValue);
+      Assert.assertTrue("Filter should have blocked configured bundle symbolic name header value", excluded);
+   }
+
+   /**
+    * Ensures that a JAR with a manifest header of 
+    * "Bundle-SymbolicName" matching a given pattern is excluded
+    */
+   @Test
+   public void notOverzealous() throws IOException
+   {
+      final boolean excluded = this.filter("org.jboss.test", " configured value which doesn't match");
+      Assert.assertTrue("Filter should not have blocked unconfigured bundle symbolic name header value", !excluded);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Runs a manifest JAR with header "Bundle-SymbolicName"
+    * with the specified value through a {@link BundleSymbolicNameExclusionFilter}
+    * with the specified configuration 
+    * 
+    * @param bundleSymbolicName
+    * @param filterConfig
+    * @throws IOException
+    */
+   private boolean filter(final String bundleSymbolicName, final String filterConfig) throws IOException
+   {
+      // Precondition checks
+      assert bundleSymbolicName != null : "bundleSymbolicName must be specified";
+      assert filterConfig != null : "filterConfig must be specified";
+
+      // Create the archive
+      final JavaArchive archive = ShrinkWrap.create("manifest.jar", JavaArchive.class).addManifestResource(new Asset()
+      {
+
+         @Override
+         public InputStream openStream()
+         {
+            return new ByteArrayInputStream(("Bundle-SymbolicName=" + bundleSymbolicName).getBytes());
+         }
+      }, "MANIFEST.MF");
+      log.info(archive.toString(true));
+
+      // Mount
+      final String archiveName = archive.getName();
+      final VirtualFile file = VFS.getChild(archiveName);
+      handles.add(VFS.mount(file, new ArchiveFileSystem(archive, provider.createTempDir(archiveName))));
+
+      // Run through the filter
+      final ExclusionFilter filter = new BundleSymbolicNameExclusionFilter(filterConfig);
+      boolean excluded = filter.exclude(file);
+      return excluded;
+   }
+
+}

Modified: projects/ejb3/components/embedded/trunk/spi/src/main/java/org/jboss/ejb3/embedded/spi/scanner/filter/ExclusionFilter.java
===================================================================
--- projects/ejb3/components/embedded/trunk/spi/src/main/java/org/jboss/ejb3/embedded/spi/scanner/filter/ExclusionFilter.java	2010-04-29 15:11:25 UTC (rev 104319)
+++ projects/ejb3/components/embedded/trunk/spi/src/main/java/org/jboss/ejb3/embedded/spi/scanner/filter/ExclusionFilter.java	2010-04-29 16:27:08 UTC (rev 104320)
@@ -44,7 +44,9 @@
     * Returns whether this {@link VirtualFile} should be
     * excluded from scanning for EJB resources.  The criteria
     * whereby a file is excluded is up to the implementation.
+    * @param The file to inspect for exclusion properties
+    * @throws IllegalArgumentException If the file is not specified
     */
-   boolean exclude(VirtualFile file);
+   boolean exclude(VirtualFile file) throws IllegalArgumentException;
 
 }




More information about the jboss-cvs-commits mailing list