Author: edwardsmj
Date: Wed Apr 22 09:17:59 2009
New Revision: 767428

URL: http://svn.apache.org/viewvc?rev=767428&view=rev
Log:
Improvements to the handling of OSGi bundles when running in development mode

Modified:
    
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java
    
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java

Modified: 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java?rev=767428&r1=767427&r2=767428&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java
 (original)
+++ 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java
 Wed Apr 22 09:17:59 2009
@@ -314,31 +314,41 @@
             }
 
             // Start all our bundles for now to help diagnose any class 
loading issues
-            //            for (Bundle bundle: bundleContext.getBundles()) {
-            //                if 
(bundle.getSymbolicName().startsWith("org.apache.tuscany.sca")) {
-            //                    if ((bundle.getState() & Bundle.ACTIVE) == 
0) {
-            //                        if (logger.isLoggable(Level.FINE)) {
-            //                            logger.fine("Starting bundle: " + 
string(bundle, false));
-            //                        }
-            //                        try {
-            //                            //bundle.start();
-            //                        } catch (Exception e) {
-            //                            logger.log(Level.SEVERE, 
e.getMessage(), e);
-            //                            // throw e;
-            //                        }
-            //                        if (logger.isLoggable(Level.FINE)) {
-            //                            logger.fine("Bundle: " + 
string(bundle, false));
-            //                        }
-            //                    }
-            //                }
-            //            }
-            //            logger.fine("Tuscany bundles are started in " + 
(System.currentTimeMillis() - activateStart) + " ms.");
+            // startBundles( bundleContext );
             return bundleContext;
 
         } catch (Exception e) {
             throw new IllegalStateException(e);
         }
     }
+    
+    /**
+     * Start all the bundles as a check for class loading issues
+     * @param bundleContext - the bundle context
+     */
+    private void startBundles( BundleContext bundleContext ) {
+       
+        for (Bundle bundle: bundleContext.getBundles()) {
+        //    if 
(bundle.getSymbolicName().startsWith("org.apache.tuscany.sca")) {
+                if ((bundle.getState() & Bundle.ACTIVE) == 0) {
+                    if (logger.isLoggable(Level.FINE)) {
+                        logger.fine("Starting bundle: " + string(bundle, 
false));
+                    } // end if
+                    try {
+                        bundle.start();
+                    } catch (Exception e) {
+                        logger.log(Level.SEVERE, e.getMessage(), e);
+                        // throw e;
+                    } // end try
+                    if (logger.isLoggable(Level.FINE)) {
+                        logger.fine("Bundle: " + string(bundle, false));
+                    } // end if
+                } //  end if
+        //    } // end if
+        } // end for
+        logger.fine("Tuscany bundles are started.");
+        return;
+    } // end startBundles
 
     public Bundle installAsBundle(Collection<URL> jarFiles, String 
libraryBundleName) throws IOException,
         BundleException {
@@ -398,9 +408,16 @@
                 logger.fine("Installing third-party jar as bundle: " + 
jarFile);
             }
             InputStream is = 
thirdPartyLibraryBundle(Collections.singleton(jarFile), symbolicName, version);
+            // try/catch and output message added 10/04/2009 Mike Edwards
+            try {
             bundle = bundleContext.installBundle(symbolicName, is);
             allBundles.put(symbolicName, bundle);
             installedBundles.add(bundle);
+            } catch (BundleException e) {
+               System.out.println("EquinoxHost:installAsBundle - 
BundleException raised when dealing with jar " + symbolicName);
+               throw (e);
+            } // end try
+            // end of addition
         }
         return bundle;
     }
@@ -416,7 +433,11 @@
 
                 // Use classpath entries from a distribution if there is one 
and the classpath
                 // entries on the current application's classloader
-                bundleLocations = runtimeClasspathEntries(true, true, false);
+               // *** Changed by Mike Edwards, 9th April 2009 ***
+               // -- this place is reached when starting from within Eclipse 
so why use the classpath??
+               // bundleLocations = runtimeClasspathEntries(true, true, false);
+               // Instead search the modules directory
+                bundleLocations = runtimeClasspathEntries(true, true, true);
             }
         }
         return bundleLocations;

Modified: 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java?rev=767428&r1=767427&r2=767428&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java
 (original)
+++ 
tuscany/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java
 Wed Apr 22 09:17:59 2009
@@ -48,6 +48,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.jar.Attributes;
@@ -240,7 +241,14 @@
      * starting with -, then some digits, then . or - or _, then some digits 
again
      * 
      */
-    private static Pattern pattern = 
Pattern.compile("-(\\d)+((\\.|-|_)(\\d)+)*");
+    // Mike Edwards 13/04/2009 - this original pattern allows for any number 
of repeated
+    // groups of digits, so that 1.2.3.4 is legal, for example.  The problem 
with this is
+    // that OSGi only deals with a maximum of 3 groups of digits...
+    // private static Pattern pattern = 
Pattern.compile("-(\\d)+((\\.|-|_)(\\d)+)*");
+    //
+    // This updated version restricts the allowed patterns to a maximum of 3 
groups of 
+    // digits so that "1", "1.2" and "1.2.3" are allowed but not "1.2.3.4" etc
+    private static Pattern pattern = 
Pattern.compile("-(\\d)+((\\.|-|_)(\\d)+){0,2}");
 
     /**
      * Returns the version number to use for the given JAR file.
@@ -265,7 +273,12 @@
         String version = "0.0.0";
         if (matcher.find()) {
             version = matcher.group();
+            // Remove the leading "-" character
             version = version.substring(1);
+            // The Pattern above allows the version string to contain "-" and 
"_" as digit separators.  
+            // OSGi only allows for "." as a separator thus any "-" and "_" 
characters in the version string must be replaced by "."
+            version = version.replace('-', '.');
+            version = version.replace('_', '.');
         }
         return version;
     }
@@ -367,6 +380,31 @@
             }
         }
     }
+    
+    /**
+     * Finds the OSGi manifest file for a JAR file, where the manifest file is 
held in a META-INF directory
+     * alongside the JAR 
+     * @param jarURL - The URL of the JAR file
+     * @return - a Manifest object corresponding to the manifest file, or NULL 
if there is no OSGi manifest
+     */
+    static private Manifest findOSGiManifest( URL jarURL ) {
+               try{
+                       File jarFile = new File( jarURL.toURI() );
+                       File theManifestFile = new File(jarFile.getParent(), 
"META-INF/MANIFEST.MF");
+                       if( theManifestFile.exists() ) {
+                               // Create manifest object by reading the 
manifest file
+                               Manifest manifest = new Manifest( new 
FileInputStream(theManifestFile) );
+                               // Check that this manifest file has the 
necessary OSGi metadata
+                               String bundleName = 
manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+                               if( bundleName != null ) {
+                                       return manifest;
+                               } // end if
+                       } // end if
+               } catch ( Exception e ) {
+                       // Could not read the manifest - continue
+               }
+               return null;
+    } // end findOSGiManifest
 
     /**
      * Generate a manifest from a list of third-party JAR files.
@@ -381,7 +419,17 @@
                                                             String 
bundleSymbolicName,
                                                             String 
bundleVersion) throws IllegalStateException {
         try {
-
+               // Added by Mike Edwards, 12/04/2009 - to handle the third 
party JAR files in the distribution that
+               // have separate OSGi manifest files provided alongside them
+               // In some cases a single JAR file is already accompanied by a 
MANIFEST.MF file, sitting in
+               // a META-INF directory alongside the JAR
+               //if( jarFiles.size() == 1 ){
+               //      URL theJar = jarFiles.iterator().next();
+               //      Manifest theManifest = findOSGiManifest( theJar );
+               //      if( theManifest != null ) return theManifest;
+               //} // end if
+               // End of addition
+               
             // List exported packages and bundle classpath entries
             StringBuffer classpath = new StringBuffer();
             StringBuffer exports = new StringBuffer();
@@ -825,7 +873,10 @@
                                                                    
jarDirectoryURLs,
                                                                    jarURLs,
                                                                    new 
StandAloneDevelopmentClassesFileNameFilter());
-                            }
+                                // Added Mike Edwards, 09/04/2009
+                                // Get hold of the Libraries that are used by 
the Tuscany modules
+                                collectDevelopmentLibraryEntries( 
modulesDirectory, jarDirectoryURLs, jarURLs );
+                            } // end if
                         }
                     }
                 }
@@ -1053,6 +1104,29 @@
     }
 
     /**
+     * A file name filter used to filter the libraries in the 
\java\sca\distribution\all\target\modules
+     * directory
+     */
+    private static class DistributionLibsFileNameFilter implements 
FilenameFilter {
+
+        public boolean accept(File dir, String name) {
+            name = name.toLowerCase();
+
+            // Include subdirectories
+            if (new File(dir, name).isDirectory()) { return true; }
+
+            // Filter out the Tuscany jars - since the development versions of 
these are used
+            // from the \target\classes directories...
+            if (name.startsWith("tuscany")) { return false; }
+
+            // Include JAR and MAR files
+            if (name.endsWith(".jar")) { return true; }
+            if (name.endsWith(".mar")) { return true; }
+            return false;
+        } // end accept
+    } // end DistributionLibsFileNameFilter
+
+    /**
      * Returns the File object representing  the given URL.
      * 
      * @param url
@@ -1108,6 +1182,34 @@
             collectTargetClassesClasspathEntries(directoryFile, jarURLs, 
filter);
 
         }
-    }
+    } // end collectDevelopmentClasspathEntries
+    
+    /**
+     * Collect the dependent Library JAR files for the development use of 
Tuscany
+     * It is assumed that these live in the 
\java\sca\distribution\all\target\modules
+     * directory, where the development modules live in \java\sca\modules, but 
that 
+     * same directory also contains prebuilt versions of the Tuscany JARs, 
which must be
+     * filtered out so as not to clash with the development versions of the 
code
+     * 
+     * @param directory - the \java\sca\modules directory
+     * @param jarDirectoryURLs
+     * @param jarURLs
+     * @throws MalformedURLException
+     */
+    private static void collectDevelopmentLibraryEntries(File modulesDirectory,
+                                                         Set<URL> 
jarDirectoryURLs,
+                                                         Set<URL> jarURLs) 
throws MalformedURLException {
+        // Get the \java\sca directory
+       File rootDirectory = modulesDirectory.getParentFile();
+       // Get the \java\sca\distribution\all\target\modules
+        String sep = File.separator;
+        File libsDirectory = new File(rootDirectory, "distribution" + sep + 
"all" + sep + "target" + sep + "modules");
+        URL libsURL = libsDirectory.toURI().toURL();
+        if (!jarDirectoryURLs.contains(libsURL) && libsDirectory.exists()) {
+            // Collect files under the libs module directory
+            jarDirectoryURLs.add(libsURL);
+            collectClasspathEntries(libsDirectory, jarURLs, new 
DistributionLibsFileNameFilter(), true);
+        } // end if
+    } // end collectDevelopmentLibraryEntries
 
 }


Reply via email to