You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2013/11/24 14:26:30 UTC

svn commit: r1544969 - in /cayenne/main/trunk/cayenne-server/src: main/java/org/apache/cayenne/configuration/osgi/ test/java/org/apache/cayenne/configuration/osgi/

Author: aadamchik
Date: Sun Nov 24 13:26:29 2013
New Revision: 1544969

URL: http://svn.apache.org/r1544969
Log:
CAY-1882 Porting to OSGi environment

warming up DataDomain under the app bundle classloader...
really a hack until CAY-1887 is properly done

Added:
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/DefaultOsgiEnvironment.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiEnvironment.java
Modified:
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactory.java
    cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactoryTest.java

Added: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/DefaultOsgiEnvironment.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/DefaultOsgiEnvironment.java?rev=1544969&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/DefaultOsgiEnvironment.java (added)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/DefaultOsgiEnvironment.java Sun Nov 24 13:26:29 2013
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.configuration.osgi;
+
+import org.apache.cayenne.di.Injector;
+
+/**
+ * @since 3.2
+ */
+public class DefaultOsgiEnvironment implements OsgiEnvironment {
+
+    private ClassLoader applicationClassLoader;
+    private ClassLoader cayenneServerClassLoader;
+    private ClassLoader cayenneDiClassLoader;
+
+    public DefaultOsgiEnvironment(ClassLoader applicationClassLoader) {
+        this.applicationClassLoader = applicationClassLoader;
+        this.cayenneDiClassLoader = Injector.class.getClassLoader();
+        this.cayenneServerClassLoader = DefaultOsgiEnvironment.class.getClassLoader();
+    }
+
+    @Override
+    public ClassLoader applicationClassLoader(String resourceName) {
+        // return preset classloader regardless of the resource name...
+        return applicationClassLoader;
+    }
+
+    @Override
+    public ClassLoader cayenneDiClassLoader() {
+        return cayenneDiClassLoader;
+    }
+
+    @Override
+    public ClassLoader cayenneServerClassLoader() {
+        return cayenneServerClassLoader;
+    }
+
+}

Added: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java?rev=1544969&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java (added)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java Sun Nov 24 13:26:29 2013
@@ -0,0 +1,76 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.configuration.osgi;
+
+import org.apache.cayenne.ConfigurationException;
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.configuration.server.DataDomainProvider;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjEntity;
+
+/**
+ * @since 3.2
+ */
+// TODO: this is really a hack until we can have fully injectable class loading
+// at the EntityResolver level per CAY-1887
+public class OsgiDataDomainProvider extends DataDomainProvider {
+
+    private OsgiEnvironment osgiEnvironment;
+
+    public OsgiDataDomainProvider(@Inject OsgiEnvironment osgiEnvironment) {
+        this.osgiEnvironment = osgiEnvironment;
+    }
+
+    @Override
+    public DataDomain get() throws ConfigurationException {
+
+        // here goes the class loading hack, temporarily setting application
+        // bundle ClassLoader to be a thread ClassLoader for runtime to start.
+
+        Thread thread = Thread.currentThread();
+        ClassLoader activeCl = thread.getContextClassLoader();
+        try {
+
+            // using fake package name... may not work with all implementations
+            // of osgiEnvironment?
+            thread.setContextClassLoader(osgiEnvironment.applicationClassLoader("com/"));
+
+            DataDomain domain = super.get();
+            EntityResolver entityResolver = domain.getEntityResolver();
+            for (ObjEntity e : entityResolver.getObjEntities()) {
+
+                // it is not enough to just call 'getObjectClass()' on
+                // ClassDescriptor - there's an optimization that prevents full
+                // descriptor resolving... so calling some other method...
+                entityResolver.getClassDescriptor(e.getName()).getProperty("__dummy__");
+                entityResolver.getCallbackRegistry();
+            }
+
+            // this triggers callbacks initialization using thread class loader
+            entityResolver.getCallbackRegistry();
+
+            return domain;
+
+        } finally {
+            thread.setContextClassLoader(activeCl);
+        }
+    }
+
+}

Added: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiEnvironment.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiEnvironment.java?rev=1544969&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiEnvironment.java (added)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiEnvironment.java Sun Nov 24 13:26:29 2013
@@ -0,0 +1,35 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.configuration.osgi;
+
+/**
+ * Encapsulates OSGi-specific environment settings that can be used to configure
+ * the rest of Cayenne.
+ * 
+ * @since 3.2
+ */
+public interface OsgiEnvironment {
+
+    ClassLoader applicationClassLoader(String resourceName);
+
+    ClassLoader cayenneDiClassLoader();
+
+    ClassLoader cayenneServerClassLoader();
+
+}

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java?rev=1544969&r1=1544968&r2=1544969&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java Sun Nov 24 13:26:29 2013
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.configuration.osgi;
 
+import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.di.AdhocObjectFactory;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
@@ -52,10 +53,10 @@ public class OsgiModule implements Modul
 
     @Override
     public void configure(Binder binder) {
-        binder.bind(AdhocObjectFactory.class).toInstance(configureObjectFactory());
-    }
+        binder.bind(OsgiEnvironment.class).toInstance(
+                new DefaultOsgiEnvironment(typeFromProjectBundle.getClassLoader()));
 
-    private AdhocObjectFactory configureObjectFactory() {
-        return new SplitClassLoaderAdhocObjectFactory(typeFromProjectBundle.getClassLoader());
+        binder.bind(AdhocObjectFactory.class).to(SplitClassLoaderAdhocObjectFactory.class);
+        binder.bind(DataDomain.class).toProvider(OsgiDataDomainProvider.class);
     }
 }

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactory.java?rev=1544969&r1=1544968&r2=1544969&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactory.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactory.java Sun Nov 24 13:26:29 2013
@@ -19,6 +19,7 @@
 package org.apache.cayenne.configuration.osgi;
 
 import org.apache.cayenne.di.AdhocObjectFactory;
+import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory;
 
 /**
@@ -27,19 +28,15 @@ import org.apache.cayenne.di.spi.Default
  * 
  * @since 3.2
  */
-public class SplitClassLoaderAdhocObjectFactory extends DefaultAdhocObjectFactory {
+class SplitClassLoaderAdhocObjectFactory extends DefaultAdhocObjectFactory {
 
     private static final String CAYENNE_PACKAGE = "org/apache/cayenne";
     private static final String CAYENNE_DI_PACKAGE_SUFFIX = "/di";
 
-    private ClassLoader applicationClassLoader;
-    private ClassLoader cayenneServerClassLoader;
-    private ClassLoader cayenneDiClassLoader;
-
-    public SplitClassLoaderAdhocObjectFactory(ClassLoader applicationClassLoader) {
-        this.applicationClassLoader = applicationClassLoader;
-        this.cayenneDiClassLoader = AdhocObjectFactory.class.getClassLoader();
-        this.cayenneServerClassLoader = SplitClassLoaderAdhocObjectFactory.class.getClassLoader();
+    private OsgiEnvironment osgiEnvironment;
+
+    SplitClassLoaderAdhocObjectFactory(@Inject OsgiEnvironment osgiEnvironment) {
+        this.osgiEnvironment = osgiEnvironment;
     }
 
     @Override
@@ -60,15 +57,15 @@ public class SplitClassLoaderAdhocObject
     }
 
     protected ClassLoader applicationClassLoader(String resourceName) {
-        return applicationClassLoader;
+        return osgiEnvironment.applicationClassLoader(resourceName);
     }
 
     protected ClassLoader cayenneDiClassLoader() {
-        return cayenneDiClassLoader;
+        return osgiEnvironment.cayenneDiClassLoader();
     }
 
     protected ClassLoader cayenneServerClassLoader() {
-        return cayenneServerClassLoader;
+        return osgiEnvironment.cayenneServerClassLoader();
     }
 
 }

Modified: cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactoryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactoryTest.java?rev=1544969&r1=1544968&r2=1544969&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactoryTest.java (original)
+++ cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/SplitClassLoaderAdhocObjectFactoryTest.java Sun Nov 24 13:26:29 2013
@@ -18,7 +18,9 @@
  ****************************************************************/
 package org.apache.cayenne.configuration.osgi;
 
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 import junit.framework.TestCase;
 
 public class SplitClassLoaderAdhocObjectFactoryTest extends TestCase {
@@ -29,18 +31,12 @@ public class SplitClassLoaderAdhocObject
         final ClassLoader diCl = mock(ClassLoader.class);
         final ClassLoader serverCl = mock(ClassLoader.class);
 
-        SplitClassLoaderAdhocObjectFactory factory = new SplitClassLoaderAdhocObjectFactory(appCl) {
-
-            @Override
-            protected ClassLoader cayenneDiClassLoader() {
-                return diCl;
-            }
-
-            @Override
-            protected ClassLoader cayenneServerClassLoader() {
-                return serverCl;
-            }
-        };
+        OsgiEnvironment osgiEnvironment = mock(OsgiEnvironment.class);
+        when(osgiEnvironment.applicationClassLoader(anyString())).thenReturn(appCl);
+        when(osgiEnvironment.cayenneDiClassLoader()).thenReturn(diCl);
+        when(osgiEnvironment.cayenneServerClassLoader()).thenReturn(serverCl);
+        
+        SplitClassLoaderAdhocObjectFactory factory = new SplitClassLoaderAdhocObjectFactory(osgiEnvironment);
 
         assertSame(appCl, factory.getClassLoader(null));
         assertSame(appCl, factory.getClassLoader(""));