Hey Ioannis,

This looks excellent and it has been an underlying topic which has
drifted in and out of conversations overs at dev@nutch from time to
time. I am as well coming clean and saying that OSGi is not something
I am familiarised with, but was very interested to hear about @
ApacheCon this year...

I wonder if it is possible for you to sum up what benefits this adds
to Gora, I'm more interested in client interaction e.g. Nutchgora
branch...

Thanks Ioannis, all the best

Lewis

On Wed, Jan 4, 2012 at 5:23 PM,  <ioca...@apache.org> wrote:
> Author: iocanel
> Date: Wed Jan  4 17:23:26 2012
> New Revision: 1227229
>
> URL: http://svn.apache.org/viewvc?rev=1227229&view=rev
> Log:
> [GORA-72] Made all artifacts proper OSGi bundles. Added ClassLoadingUtils 
> which will fallback to thread context classloader if Class.forName fails.
>
> Added:
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ClassLoadingUtils.java
> Modified:
>    incubator/gora/trunk/gora-cassandra/pom.xml
>    incubator/gora/trunk/gora-core/pom.xml
>    
> incubator/gora/trunk/gora-core/src/examples/java/org/apache/gora/examples/mapreduce/QueryCounter.java
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/query/impl/QueryBase.java
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/DataStoreFactory.java
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/impl/DataStoreBase.java
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/IOUtils.java
>    
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ReflectionUtils.java
>    incubator/gora/trunk/gora-sql/pom.xml
>    
> incubator/gora/trunk/gora-sql/src/main/java/org/apache/gora/sql/store/SqlStore.java
>    
> incubator/gora/trunk/gora-sql/src/test/java/org/apache/gora/sql/GoraSqlTestDriver.java
>    incubator/gora/trunk/pom.xml
>
> Modified: incubator/gora/trunk/gora-cassandra/pom.xml
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-cassandra/pom.xml?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- incubator/gora/trunk/gora-cassandra/pom.xml (original)
> +++ incubator/gora/trunk/gora-cassandra/pom.xml Wed Jan  4 17:23:26 2012
> @@ -27,10 +27,15 @@
>         <relativePath>../</relativePath>
>     </parent>
>     <artifactId>gora-cassandra</artifactId>
> -    <packaging>jar</packaging>
> +    <packaging>bundle</packaging>
>
>     <name>Apache Gora :: Cassandra</name>
>
> +    <properties>
> +        <osgi.import>*</osgi.import>
> +        
> <osgi.export>org.apache.gora.cassandra*;version="${project.version}";-noimport:=true</osgi.export>
> +    </properties>
> +
>     <build>
>         <directory>target</directory>
>         <outputDirectory>target/classes</outputDirectory>
>
> Modified: incubator/gora/trunk/gora-core/pom.xml
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/pom.xml?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- incubator/gora/trunk/gora-core/pom.xml (original)
> +++ incubator/gora/trunk/gora-core/pom.xml Wed Jan  4 17:23:26 2012
> @@ -25,10 +25,15 @@
>         <relativePath>../</relativePath>
>     </parent>
>     <artifactId>gora-core</artifactId>
> -    <packaging>jar</packaging>
> +    <packaging>bundle</packaging>
>
>     <name>Apache Gora :: Core</name>
>
> +    <properties>
> +        <osgi.import>*</osgi.import>
> +        
> <osgi.export>org.apache.gora*;version="${project.version}";-noimport:=true</osgi.export>
> +    </properties>
> +
>     <build>
>         <directory>target</directory>
>         <outputDirectory>target/classes</outputDirectory>
>
> Modified: 
> incubator/gora/trunk/gora-core/src/examples/java/org/apache/gora/examples/mapreduce/QueryCounter.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/examples/java/org/apache/gora/examples/mapreduce/QueryCounter.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/examples/java/org/apache/gora/examples/mapreduce/QueryCounter.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/examples/java/org/apache/gora/examples/mapreduce/QueryCounter.java
>  Wed Jan  4 17:23:26 2012
> @@ -32,6 +32,7 @@ import org.apache.hadoop.mapreduce.Job;
>  import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
>  import org.apache.hadoop.util.Tool;
>  import org.apache.hadoop.util.ToolRunner;
> +import org.apache.gora.util.ClassLoadingUtils;
>
>  /**
>  * Example Hadoop job to count the row of a gora {@link Query}.
> @@ -120,8 +121,8 @@ public class QueryCounter<K, T extends P
>       return 1;
>     }
>
> -    Class<K> keyClass = (Class<K>) Class.forName(args[0]);
> -    Class<T> persistentClass = (Class<T>) Class.forName(args[1]);
> +    Class<K> keyClass = (Class<K>) ClassLoadingUtils.loadClass(args[0]);
> +    Class<T> persistentClass = (Class<T>) 
> ClassLoadingUtils.loadClass(args[1]);
>
>     DataStore<K,T> dataStore;
>     Configuration conf = new Configuration();
>
> Modified: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/query/impl/QueryBase.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/query/impl/QueryBase.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/query/impl/QueryBase.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/query/impl/QueryBase.java
>  Wed Jan  4 17:23:26 2012
> @@ -29,6 +29,7 @@ import org.apache.gora.persistency.Persi
>  import org.apache.gora.query.Query;
>  import org.apache.gora.query.Result;
>  import org.apache.gora.store.DataStore;
> +import org.apache.gora.util.ClassLoadingUtils;
>  import org.apache.gora.util.IOUtils;
>  import org.apache.hadoop.conf.Configuration;
>  import org.apache.hadoop.io.Text;
> @@ -217,8 +218,7 @@ public String[] getFields() {
>   public void readFields(DataInput in) throws IOException {
>     String dataStoreClass = Text.readString(in);
>     try {
> -      dataStore = (DataStore<K, T>) ReflectionUtils.newInstance(
> -          Class.forName(dataStoreClass), conf);
> +      dataStore = (DataStore<K, T>) 
> ReflectionUtils.newInstance(ClassLoadingUtils.loadClass(dataStoreClass), 
> conf);
>       dataStore.readFields(in);
>     } catch (ClassNotFoundException ex) {
>       throw new IOException(ex);
>
> Modified: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/DataStoreFactory.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/DataStoreFactory.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/DataStoreFactory.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/DataStoreFactory.java
>  Wed Jan  4 17:23:26 2012
> @@ -26,6 +26,7 @@ import org.apache.commons.logging.Log;
>  import org.apache.commons.logging.LogFactory;
>  import org.apache.gora.persistency.Persistent;
>  import org.apache.gora.store.impl.DataStoreBase;
> +import org.apache.gora.util.ClassLoadingUtils;
>  import org.apache.gora.util.GoraException;
>  import org.apache.gora.util.ReflectionUtils;
>  import org.apache.hadoop.conf.Configurable;
> @@ -159,8 +160,8 @@ public class DataStoreFactory {
>     throws GoraException {
>
>     try {
> -      Class k = Class.forName(keyClass);
> -      Class p = Class.forName(persistentClass);
> +      Class k = ClassLoadingUtils.loadClass(keyClass);
> +      Class p = ClassLoadingUtils.loadClass(persistentClass);
>       return getDataStore(dataStoreClass, k, p, conf);
>     } catch(GoraException ex) {
>       throw ex;
>
> Modified: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/impl/DataStoreBase.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/impl/DataStoreBase.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/impl/DataStoreBase.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/store/impl/DataStoreBase.java
>  Wed Jan  4 17:23:26 2012
> @@ -35,6 +35,7 @@ import org.apache.gora.persistency.impl.
>  import org.apache.gora.store.DataStore;
>  import org.apache.gora.store.DataStoreFactory;
>  import org.apache.gora.util.AvroUtils;
> +import org.apache.gora.util.ClassLoadingUtils;
>  import org.apache.gora.util.StringUtils;
>  import org.apache.hadoop.conf.Configuration;
>  import org.apache.hadoop.io.Text;
> @@ -173,8 +174,8 @@ public T get(K key) throws IOException {
>   @SuppressWarnings("unchecked")
>   public void readFields(DataInput in) throws IOException {
>     try {
> -      Class<K> keyClass = (Class<K>) Class.forName(Text.readString(in));
> -      Class<T> persistentClass = 
> (Class<T>)Class.forName(Text.readString(in));
> +      Class<K> keyClass = (Class<K>) 
> ClassLoadingUtils.loadClass(Text.readString(in));
> +      Class<T> persistentClass = 
> (Class<T>)ClassLoadingUtils.loadClass(Text.readString(in));
>       initialize(keyClass, persistentClass, DataStoreFactory.properties);
>
>     } catch (ClassNotFoundException ex) {
>
> Added: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ClassLoadingUtils.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ClassLoadingUtils.java?rev=1227229&view=auto
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ClassLoadingUtils.java
>  (added)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ClassLoadingUtils.java
>  Wed Jan  4 17:23:26 2012
> @@ -0,0 +1,64 @@
> +package org.apache.gora.util;
> +
> +public class ClassLoadingUtils {
> +
> +    private ClassLoadingUtils() {
> +        //Utility Class
> +    }
> +
> +    /**
> +     * Loads a class using the class loader.
> +     * 1. The class loader of the current class is being used.
> +     * 2. The thread context class loader is being used.
> +     * If both approaches fail, returns null.
> +     *
> +     * @param className    The name of the class to load.
> +     * @return The class or null if no class loader could load the class.
> +     */
> +    public static Class<?> loadClass(String className) throws 
> ClassNotFoundException {
> +        return 
> ClassLoadingUtils.loadClass(ClassLoadingUtils.class,className);
> +    }
> +
> +    /**
> +     * Loads a class using the class loader.
> +     * 1. The class loader of the context class is being used.
> +     * 2. The thread context class loader is being used.
> +     * If both approaches fail, returns null.
> +     *
> +     * @param contextClass The name of a context class to use.
> +     * @param className    The name of the class to load
> +     * @return The class or null if no class loader could load the class.
> +     */
> +    public static Class<?> loadClass(Class<?> contextClass, String 
> className) throws ClassNotFoundException {
> +        Class<?> clazz = null;
> +        if (contextClass.getClassLoader() != null) {
> +            clazz = loadClass(className, contextClass.getClassLoader());
> +        }
> +        if (clazz == null && Thread.currentThread().getContextClassLoader() 
> != null) {
> +            clazz = loadClass(className, 
> Thread.currentThread().getContextClassLoader());
> +        }
> +        if (clazz == null) {
> +            throw new ClassNotFoundException("Failed to load class" + 
> className);
> +        }
> +        return clazz;
> +    }
> +
> +    /**
> +     * Loads a {@link Class} from the specified {@link ClassLoader} without 
> throwing {@ClassNotFoundException}.
> +     *
> +     * @param className
> +     * @param classLoader
> +     * @return
> +     */
> +    private static Class<?> loadClass(String className, ClassLoader 
> classLoader) {
> +        Class<?> clazz = null;
> +        if (classLoader != null && className != null) {
> +            try {
> +                clazz = classLoader.loadClass(className);
> +            } catch (ClassNotFoundException e) {
> +                //Ignore and return null
> +            }
> +        }
> +        return clazz;
> +    }
> +}
>
> Modified: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/IOUtils.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/IOUtils.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/IOUtils.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/IOUtils.java
>  Wed Jan  4 17:23:26 2012
> @@ -189,7 +189,7 @@ public class IOUtils {
>   public static<T> T deserialize(Configuration conf, DataInput in
>       , T obj , String objClass) throws IOException, ClassNotFoundException {
>
> -    Class<T> c = (Class<T>) Class.forName(objClass);
> +    Class<T> c = (Class<T>) ClassLoadingUtils.loadClass(objClass);
>
>     return deserialize(conf, in, obj, c);
>   }
> @@ -233,7 +233,7 @@ public class IOUtils {
>   public static<T> T deserialize(Configuration conf, DataInput in
>       , T obj) throws IOException, ClassNotFoundException {
>     String clazz = Text.readString(in);
> -    Class<T> c = (Class<T>)Class.forName(clazz);
> +    Class<T> c = (Class<T>)ClassLoadingUtils.loadClass(clazz);
>     return deserialize(conf, in, obj, c);
>   }
>
> @@ -477,7 +477,7 @@ public class IOUtils {
>     String classKey = dataKey + "._class";
>     String className = conf.get(classKey);
>     try {
> -      T obj = (T) DefaultStringifier.load(conf, dataKey, 
> Class.forName(className));
> +      T obj = (T) DefaultStringifier.load(conf, dataKey, 
> ClassLoadingUtils.loadClass(className));
>       return obj;
>     } catch (Exception ex) {
>       throw new IOException(ex);
>
> Modified: 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ReflectionUtils.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ReflectionUtils.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ReflectionUtils.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-core/src/main/java/org/apache/gora/util/ReflectionUtils.java
>  Wed Jan  4 17:23:26 2012
> @@ -87,7 +87,7 @@ public class ReflectionUtils {
>     if(classStr == null) {
>       throw new IllegalArgumentException("class cannot be null");
>     }
> -    Class<?> clazz = Class.forName(classStr);
> +    Class<?> clazz = ClassLoadingUtils.loadClass(classStr);
>     return newInstance(clazz);
>   }
>
>
> Modified: incubator/gora/trunk/gora-sql/pom.xml
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-sql/pom.xml?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- incubator/gora/trunk/gora-sql/pom.xml (original)
> +++ incubator/gora/trunk/gora-sql/pom.xml Wed Jan  4 17:23:26 2012
> @@ -24,10 +24,15 @@
>         <version>0.2-SNAPSHOT</version>
>     </parent>
>     <artifactId>gora-sql</artifactId>
> -    <packaging>jar</packaging>
> +    <packaging>bundle</packaging>
>
>     <name>Apache Gora :: SQL</name>
>
> +    <properties>
> +        <osgi.import>*</osgi.import>
> +        
> <osgi.export>org.apache.gora.sql*;version="${project.version}";-noimport:=true</osgi.export>
> +    </properties>
> +
>     <build>
>         <directory>target</directory>
>         <outputDirectory>target/classes</outputDirectory>
> @@ -116,10 +121,10 @@
>             <artifactId>jdom</artifactId>
>         </dependency>
>
> -        <dependency>
> +        <!--dependency>
>             <groupId>com.healthmarketscience.sqlbuilder</groupId>
>             <artifactId>sqlbuilder</artifactId>
> -        </dependency>
> +        </dependency-->
>
>         <!-- Logging Dependencies -->
>         <dependency>
>
> Modified: 
> incubator/gora/trunk/gora-sql/src/main/java/org/apache/gora/sql/store/SqlStore.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-sql/src/main/java/org/apache/gora/sql/store/SqlStore.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-sql/src/main/java/org/apache/gora/sql/store/SqlStore.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-sql/src/main/java/org/apache/gora/sql/store/SqlStore.java
>  Wed Jan  4 17:23:26 2012
> @@ -65,6 +65,7 @@ import org.apache.gora.sql.util.SqlUtils
>  import org.apache.gora.store.DataStoreFactory;
>  import org.apache.gora.store.impl.DataStoreBase;
>  import org.apache.gora.util.AvroUtils;
> +import org.apache.gora.util.ClassLoadingUtils;
>  import org.apache.gora.util.IOUtils;
>  import org.apache.gora.util.StringUtils;
>  import org.jdom.Document;
> @@ -732,7 +733,7 @@ public class SqlStore<K, T extends Persi
>     try {
>       Connection connection = null;
>
> -      Class.forName(jdbcDriverClass);
> +      ClassLoadingUtils.loadClass(jdbcDriverClass);
>       if(jdbcUsername == null || jdbcUsername.length() == 0) {
>         connection = DriverManager.getConnection(jdbcUrl);
>       } else {
>
> Modified: 
> incubator/gora/trunk/gora-sql/src/test/java/org/apache/gora/sql/GoraSqlTestDriver.java
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/gora-sql/src/test/java/org/apache/gora/sql/GoraSqlTestDriver.java?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- 
> incubator/gora/trunk/gora-sql/src/test/java/org/apache/gora/sql/GoraSqlTestDriver.java
>  (original)
> +++ 
> incubator/gora/trunk/gora-sql/src/test/java/org/apache/gora/sql/GoraSqlTestDriver.java
>  Wed Jan  4 17:23:26 2012
> @@ -24,6 +24,7 @@ import java.util.Properties;
>
>  import org.apache.gora.GoraTestDriver;
>  import org.apache.gora.sql.store.SqlStore;
> +import org.apache.gora.util.ClassLoadingUtils;
>  import org.apache.hadoop.util.StringUtils;
>  import org.hsqldb.Server;
>
> @@ -99,7 +100,7 @@ public class GoraSqlTestDriver extends G
>   private Connection createConnection(String driverClassName
>       , String url) throws Exception {
>
> -    Class.forName(driverClassName);
> +    ClassLoadingUtils.loadClass(driverClassName);
>     Connection connection = DriverManager.getConnection(url);
>     connection.setAutoCommit(false);
>     return connection;
>
> Modified: incubator/gora/trunk/pom.xml
> URL: 
> http://svn.apache.org/viewvc/incubator/gora/trunk/pom.xml?rev=1227229&r1=1227228&r2=1227229&view=diff
> ==============================================================================
> --- incubator/gora/trunk/pom.xml (original)
> +++ incubator/gora/trunk/pom.xml Wed Jan  4 17:23:26 2012
> @@ -21,7 +21,6 @@
>        <groupId>org.apache</groupId>
>        <artifactId>apache</artifactId>
>        <version>9</version>
> -       <relativePath />
>      </parent>
>
>     <groupId>org.apache.gora</groupId>
> @@ -107,6 +106,40 @@
>                     
> <tagBase>https://svn.apache.org/repos/asf/incubator/gora/tags/</tagBase>
>                 </configuration>
>             </plugin>
> +            <plugin>
> +                <groupId>org.apache.felix</groupId>
> +                <artifactId>maven-bundle-plugin</artifactId>
> +                <version>${maven-bundle-plugin.version}</version>
> +                <extensions>true</extensions>
> +                <inherited>true</inherited>
> +                <configuration>
> +                    <instructions>
> +                        <Bundle-Name>${project.name}</Bundle-Name>
> +                        
> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
> +                        <Export-Package>${osgi.export}</Export-Package>
> +                        <Import-Package>${osgi.import}</Import-Package>
> +                        
> <DynamicImport-Package>${osgi.dynamic.import}</DynamicImport-Package>
> +                        <Private-Package>${osgi.private}</Private-Package>
> +                        <Require-Bundle>${osgi.bundles}</Require-Bundle>
> +                        
> <Bundle-Activator>${osgi.activator}</Bundle-Activator>
> +                    </instructions>
> +                    <supportedProjectTypes>
> +                        <supportedProjectType>jar</supportedProjectType>
> +                        <supportedProjectType>war</supportedProjectType>
> +                        <supportedProjectType>bundle</supportedProjectType>
> +                    </supportedProjectTypes>
> +                    <unpackBundle>true</unpackBundle>
> +                </configuration>
> +                <executions>
> +                    <execution>
> +                        <id>bundle-manifest</id>
> +                        <phase>process-classes</phase>
> +                        <goals>
> +                            <goal>manifest</goal>
> +                        </goals>
> +                    </execution>
> +                </executions>
> +            </plugin>
>         </plugins>
>     </build>
>
> @@ -153,6 +186,7 @@
>         
> <build-helper-maven-plugin.version>1.5</build-helper-maven-plugin.version>
>         <maven-surfire-plugin.version>2.11</maven-surfire-plugin.version>
>         <maven-release-plugin.version>2.1</maven-release-plugin.version>
> +        <maven-bundle-plugin.version>2.3.6</maven-bundle-plugin.version>
>     </properties>
>
>     <dependencyManagement>
>
>



-- 
Lewis

Reply via email to