Index: src/main/java/com/sun/enterprise/naming/impl/SerialContext.java =================================================================== --- src/main/java/com/sun/enterprise/naming/impl/SerialContext.java (revision 27697) +++ src/main/java/com/sun/enterprise/naming/impl/SerialContext.java (working copy) @@ -35,6 +35,7 @@ import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; import javax.naming.*; +import javax.naming.spi.ObjectFactory; import java.rmi.RemoteException; import java.util.Enumeration; import java.util.Hashtable; @@ -49,9 +50,9 @@ import javax.rmi.PortableRemoteObject; import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.internal.api.ClassLoaderHierarchy; - import org.omg.CORBA.ORB; @@ -119,6 +120,9 @@ // Allows special optimized intra-server naming service access private boolean intraServerLookups; + // Common Class Loader. It is used as a fallback classloader to locate + // GlassFish object factories. + private ClassLoader commonCL; /** * NOTE: ALL "stickyContext" LOGIC REMOVED FOR INITIAL V3 RELEASE. WE'LLl @@ -233,7 +237,10 @@ } orb = orbFromEnv; - + if (habitat != null) { // can happen in test mode + ClassLoaderHierarchy clh = habitat.getByContract(ClassLoaderHierarchy.class); + if (clh != null) commonCL = clh.getCommonClassLoader(); + } } /** @@ -424,9 +431,7 @@ if (obj instanceof Context) { return new SerialContext(name, myEnv, habitat); } - Object retObj = javax.naming.spi.NamingManager - .getObjectInstance(obj, new CompositeName(name), null, - myEnv); + Object retObj = getObjectInstance(name, obj); return retObj; } @@ -459,7 +464,98 @@ } + private Object getObjectInstance(String name, Object obj) throws Exception + { + Object retObj = javax.naming.spi.NamingManager + .getObjectInstance(obj, new CompositeName(name), null, + myEnv); + if (retObj == obj) { + // NamingManager.getObjectInstance() returns the same object + // when it can't find the factory class. Since NamingManager + // uses Thread's context class loader to locate factory classes, + // it may not be able to locate the various GlassFish factories + // when lookup is performed outside of a Java EE context like + // inside an OSGi bundle's activator. + // So, let's see if using CommonClassLoader helps or not. + // We will only try with CommonClassLoader when the passed object + // reference has a factory class name set. + + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + if (tccl != commonCL) { + Reference ref = getReference(obj); + if (ref != null) { + _logger.logp(Level.INFO, "SerialContext", + "getObjectInstance", + "Trying with CommonClassLoader for name {0} ", + new Object[]{name}); + ObjectFactory factory = getObjectFactory(ref, commonCL); + if (factory != null) { + retObj = factory.getObjectInstance( + ref, new CompositeName(name), null, myEnv); + } + if (retObj != obj) { + _logger.logp(Level.INFO, "SerialContext", + "getObjectInstance", + "Found with CommonClassLoader"); + } + } + } + } + return retObj; + } + /** + * This method tries to check if the passed object is a Reference or + * Refenciable. If it is a Reference, it just casts it to a Reference and + * returns, else if it is a Referenceable, it tries to get a Reference from + * the Referenceable and returns that, otherwise, it returns null. + * + * @param obj + * @return + * @throws NamingException + */ + private Reference getReference(Object obj) throws NamingException + { + Reference ref = null; + if (obj instanceof Reference) { + ref = (Reference) obj; + } else if (obj instanceof Referenceable) { + ref = ((Referenceable)(obj)).getReference(); + } + + return ref; + } + + /** + * It tries to load the factory class for the given reference using the + * given class loader and return an instance of the same. Returns null + * if it can't load the class. + * + * @param ref + * @param cl + * @return + * @throws IllegalAccessException + * @throws InstantiationException + */ + private ObjectFactory getObjectFactory(Reference ref, ClassLoader cl) + throws IllegalAccessException, InstantiationException + { + String factoryName = ref.getFactoryClassName(); + if (factoryName != null) { + try + { + Class c = Class.forName(factoryName, false, cl); + return (ObjectFactory)c.newInstance(); + } + catch (ClassNotFoundException e) + { + // ignore only CNFE, all other exceptions are considered errors + } + } + return null; + } + + /** * Lookup the specifed name in the context. Returns the resolved object. * * @return the resolved object. Index: src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactoryFactory.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactoryFactory.java (revision 0) +++ src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactoryFactory.java (revision 0) @@ -0,0 +1,57 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + + +package com.sun.enterprise.naming.util; + +/** + * @author Sanjeeb.Sahoo@Sun.COM + */ +/* package */ class ObjectInputOutputStreamFactoryFactory +{ + // default is non-OSGi factory + private static ObjectInputOutputStreamFactory factory = + new NonOSGiObjectInputOutputStreamFactoryImpl(); + + /* package */ static void setFactory(ObjectInputOutputStreamFactory factory) + { + ObjectInputOutputStreamFactoryFactory.factory = factory; + } + + public static ObjectInputOutputStreamFactory getFactory(){ + return factory; + } +} Index: src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactory.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactory.java (revision 0) +++ src/main/java/com/sun/enterprise/naming/util/ObjectInputOutputStreamFactory.java (revision 0) @@ -0,0 +1,53 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + + +package com.sun.enterprise.naming.util; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * @author Sanjeeb.Sahoo@Sun.COM + */ +public interface ObjectInputOutputStreamFactory +{ + ObjectInputStream createObjectInputStream(InputStream in) throws IOException; + ObjectOutputStream createObjectOutputStream(OutputStream out) throws IOException; +} Index: src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java (revision 27697) +++ src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java (working copy) @@ -24,6 +24,7 @@ import com.sun.enterprise.naming.spi.NamingObjectFactory; import com.sun.enterprise.naming.spi.NamingUtils; +import static com.sun.enterprise.naming.util.ObjectInputOutputStreamFactoryFactory.*; import org.jvnet.hk2.annotations.Scoped; import org.jvnet.hk2.annotations.Service; import org.jvnet.hk2.component.Singleton; @@ -77,7 +78,7 @@ try { // first serialize the object ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); + ObjectOutputStream oos = getFactory().createObjectOutputStream(bos); oos.writeObject(obj); oos.flush(); byte[] data = bos.toByteArray(); @@ -86,10 +87,7 @@ // now deserialize it ByteArrayInputStream bis = new ByteArrayInputStream(data); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - ObjectInputStream ois = new ObjectInputStreamWithLoader(bis, cl); - - + ObjectInputStream ois = getFactory().createObjectInputStream(bis); return ois.readObject(); } catch (Exception ex) { Index: src/main/java/com/sun/enterprise/naming/util/OSGiObjectInputOutputStreamFactoryImpl.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/OSGiObjectInputOutputStreamFactoryImpl.java (revision 0) +++ src/main/java/com/sun/enterprise/naming/util/OSGiObjectInputOutputStreamFactoryImpl.java (revision 0) @@ -0,0 +1,123 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + + +package com.sun.enterprise.naming.util; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.PackageAdmin; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.ObjectStreamClass; + +/** + * @author Sanjeeb.Sahoo@Sun.COM + */ +public class OSGiObjectInputOutputStreamFactoryImpl + implements ObjectInputOutputStreamFactory +{ + private BundleContext ctx; + PackageAdmin pkgAdm; + + // Since bundle id starts with 0, we use -1 to indicate a non-bundle + private static final long NOT_A_BUNDLE_ID = -1; + + public OSGiObjectInputOutputStreamFactoryImpl(BundleContext ctx) + { + this.ctx = ctx; + ServiceReference ref = ctx.getServiceReference(PackageAdmin.class.getName()); + pkgAdm = PackageAdmin.class.cast(ctx.getService(ref)); + } + + public ObjectInputStream createObjectInputStream(InputStream in) + throws IOException + { + return new OSGiObjectInputStream(in); + } + + public ObjectOutputStream createObjectOutputStream(OutputStream out) + throws IOException + { + return new OSGiObjectOutputStream(out); + } + + private class OSGiObjectInputStream extends ObjectInputStream + { + public OSGiObjectInputStream(InputStream in) throws IOException + { + super(in); + } + + @Override + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException + { + long bundleId = readLong(); + if (bundleId != NOT_A_BUNDLE_ID) { + Bundle b = ctx.getBundle(bundleId); + return b.loadClass(desc.getName()); + } else { + return super.resolveClass(desc); + } + } + + } + + private class OSGiObjectOutputStream extends ObjectOutputStream { + private OSGiObjectOutputStream(OutputStream out) throws IOException + { + super(out); + } + + @Override + protected void annotateClass(Class cl) throws IOException + { + long id = NOT_A_BUNDLE_ID; + Bundle b = pkgAdm.getBundle(cl); + if (b != null) { + id = b.getBundleId(); + } + writeLong(id); + } + } + +} Index: src/main/java/com/sun/enterprise/naming/util/NamingActivator.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/NamingActivator.java (revision 0) +++ src/main/java/com/sun/enterprise/naming/util/NamingActivator.java (revision 0) @@ -0,0 +1,60 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + + +package com.sun.enterprise.naming.util; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import com.sun.enterprise.naming.util.ObjectInputOutputStreamFactoryFactory; +import com.sun.enterprise.naming.util.OSGiObjectInputOutputStreamFactoryImpl; + +/** + * @author Sanjeeb.Sahoo@Sun.COM + */ +public class NamingActivator implements BundleActivator +{ + public void start(BundleContext context) throws Exception + { + System.out.println(this + " called"); + ObjectInputOutputStreamFactoryFactory.setFactory( + new OSGiObjectInputOutputStreamFactoryImpl(context)); + } + + public void stop(BundleContext context) throws Exception + { + } +} Index: src/main/java/com/sun/enterprise/naming/util/NonOSGiObjectInputOutputStreamFactoryImpl.java =================================================================== --- src/main/java/com/sun/enterprise/naming/util/NonOSGiObjectInputOutputStreamFactoryImpl.java (revision 0) +++ src/main/java/com/sun/enterprise/naming/util/NonOSGiObjectInputOutputStreamFactoryImpl.java (revision 0) @@ -0,0 +1,64 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + + +package com.sun.enterprise.naming.util; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * @author Sanjeeb.Sahoo@Sun.COM + */ +public class NonOSGiObjectInputOutputStreamFactoryImpl + implements ObjectInputOutputStreamFactory +{ + public ObjectInputStream createObjectInputStream(InputStream in) + throws IOException + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + return new ObjectInputStreamWithLoader(in, loader); + } + + public ObjectOutputStream createObjectOutputStream(OutputStream out) + throws IOException + { + return new ObjectOutputStream(out); + } +} Index: osgi.bundle =================================================================== --- osgi.bundle (revision 27697) +++ osgi.bundle (working copy) @@ -1,3 +1,4 @@ +Bundle-Activator: com.sun.enterprise.naming.util.NamingActivator -exportcontents: \ com.sun.enterprise.naming.impl; \ com.sun.enterprise.naming.spi; \ Index: pom.xml =================================================================== --- pom.xml (revision 27697) +++ pom.xml (working copy) @@ -78,5 +78,12 @@ orb-connector ${project.version} + + + org.osgi + osgi_R4_core + 1.0 + provided +