[Jboss-cvs] JBossAS SVN: r56982 - in projects/microcontainer/trunk/container/src/main/org/jboss/virtual: . classloading
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Sep 19 19:50:42 EDT 2006
Author: scott.stark at jboss.org
Date: 2006-09-19 19:50:39 -0400 (Tue, 19 Sep 2006)
New Revision: 56982
Added:
projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/
projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/SecurityActions.java
projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoader.java
projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoaderFactory.java
Log:
Port the vfs class loader to the virtual package
Added: projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/SecurityActions.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/SecurityActions.java 2006-09-19 23:25:01 UTC (rev 56981)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/SecurityActions.java 2006-09-19 23:50:39 UTC (rev 56982)
@@ -0,0 +1,130 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.virtual.classloading;
+
+import java.security.AccessController;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+
+import org.jboss.virtual.VFS;
+
+/**
+ * Package priviledged actions
+ *
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 55183 $
+ */
+class SecurityActions
+{
+ static PrivilegedAction<Policy> getPolicyAction = new PrivilegedAction<Policy>() {
+ public Policy run()
+ {
+ return Policy.getPolicy();
+ }
+ };
+
+ interface ClassLoaderActions
+ {
+ ClassLoaderActions PRIVILEGED = new ClassLoaderActions() {
+ public VFSClassLoader newClassLoader(final String[] paths,
+ final VFS vfs, final ClassLoader parent)
+ {
+ PrivilegedAction<VFSClassLoader> action = new PrivilegedAction<VFSClassLoader>() {
+ public VFSClassLoader run()
+ {
+ ClassLoader theParent = parent;
+ if (parent == null)
+ theParent = Thread.currentThread().getContextClassLoader();
+ return new VFSClassLoader(paths, vfs, theParent);
+ }
+ };
+ return AccessController.doPrivileged(action);
+ }
+
+ public Policy getPolicy()
+ {
+ return AccessController.doPrivileged(getPolicyAction);
+ }
+ };
+
+ ClassLoaderActions NON_PRIVILEGED = new ClassLoaderActions() {
+ public VFSClassLoader newClassLoader(final String[] paths,
+ final VFS vfs, final ClassLoader parent)
+ {
+ ClassLoader theParent = parent;
+ if (parent == null)
+ theParent = Thread.currentThread().getContextClassLoader();
+ return new VFSClassLoader(paths, vfs, theParent);
+ }
+
+ public Policy getPolicy()
+ {
+ return Policy.getPolicy();
+ }
+ };
+
+ VFSClassLoader newClassLoader(final String[] paths, final VFS vfs, ClassLoader parent);
+
+ Policy getPolicy();
+ }
+
+ static VFSClassLoader newClassLoader(final String[] paths,
+ final VFS vfs)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return ClassLoaderActions.NON_PRIVILEGED.newClassLoader(paths, vfs, null);
+ }
+ else
+ {
+ return ClassLoaderActions.PRIVILEGED.newClassLoader(paths, vfs, null);
+ }
+ }
+
+ static VFSClassLoader newClassLoader(final String[] paths,
+ final VFS vfs, ClassLoader parent)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return ClassLoaderActions.NON_PRIVILEGED.newClassLoader(paths, vfs,
+ parent);
+ }
+ else
+ {
+ return ClassLoaderActions.PRIVILEGED
+ .newClassLoader(paths, vfs, parent);
+ }
+ }
+
+ static Policy getPolicy()
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return ClassLoaderActions.NON_PRIVILEGED.getPolicy();
+ }
+ else
+ {
+ return ClassLoaderActions.PRIVILEGED.getPolicy();
+ }
+ }
+
+}
Added: projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoader.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoader.java 2006-09-19 23:25:01 UTC (rev 56981)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoader.java 2006-09-19 23:50:39 UTC (rev 56982)
@@ -0,0 +1,376 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.virtual.classloading;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
+
+import org.jboss.classloading.spi.ClassLoadingDomain;
+import org.jboss.classloading.spi.DomainClassLoader;
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+
+/** A class loader that obtains classes and resources from a VFS.
+ *
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 56428 $
+ */
+public class VFSClassLoader extends SecureClassLoader
+ implements DomainClassLoader
+{
+ private static Logger log = Logger.getLogger(VFSClassLoader.class);
+
+ protected static class ClassPathVFS
+ {
+ private ArrayList<String> searchCtxs = new ArrayList<String>();
+ private VFS vfs;
+ protected ClassPathVFS(String[] searchCtxs, VFS vfs)
+ {
+ this.searchCtxs.addAll(Arrays.asList(searchCtxs));
+ this.vfs = vfs;
+ }
+ }
+ protected ArrayList<ClassPathVFS> classpath = new ArrayList<ClassPathVFS>();
+
+ /**
+ * Create a class loader given a search path VFS, and default parent class
+ * loader.
+ * @param searchCtxs - the paths from the VFS that make up the class loader path
+ * @param vfs - the VFS used to resolve and load classes and resources
+ */
+ public VFSClassLoader(String[] searchCtxs, VFS vfs)
+ {
+ String[] resolvedCtxs = searchCtxs;
+ try
+ {
+ resolvedCtxs = resolveSearchCtxs(searchCtxs, vfs);
+ }
+ catch(IOException e)
+ {
+ log.warn("Failed to resolve searchCtxs", e);
+ }
+ ClassPathVFS cp = new ClassPathVFS(resolvedCtxs, vfs);
+ classpath.add(cp);
+ }
+ /**
+ * Create a class loader given a search path VFS, and given parent class
+ * loader.
+ * @param searchCtxs - the paths from the VFS that make up the class loader path
+ * @param vfs - the VFS used to resolve and load classes and resources
+ * @param parent - the parent class loader to use
+ */
+ public VFSClassLoader(String[] searchCtxs, VFS vfs, ClassLoader parent)
+ {
+ super(parent);
+ String[] resolvedCtxs = searchCtxs;
+ try
+ {
+ resolvedCtxs = resolveSearchCtxs(searchCtxs, vfs);
+ }
+ catch(IOException e)
+ {
+ log.warn("Failed to resolve searchCtxs", e);
+ }
+ ClassPathVFS cp = new ClassPathVFS(resolvedCtxs, vfs);
+ classpath.add(cp);
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.jboss.classloading.spi.DomainClassLoader#getClasspath()
+ */
+ public URL[] getClasspath()
+ {
+ ArrayList<URL> cp = new ArrayList<URL>(classpath.size());
+ for(ClassPathVFS entry : classpath)
+ {
+ try
+ {
+ URL baseURL = entry.vfs.getRoot().toURL();
+ for(String path : entry.searchCtxs)
+ {
+ try
+ {
+ URL entryURL = new URL(baseURL, path);
+ cp.add(entryURL);
+ }
+ catch(MalformedURLException e)
+ {
+ log.debug("Failed to parse path: "+path, e);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ log.debug("Failed to parse entry: "+entry, e);
+ }
+ }
+ URL[] theClasspath = new URL[cp.size()];
+ cp.toArray(theClasspath);
+ return theClasspath;
+ }
+
+ /**
+ * TODO
+ * @see org.jboss.classloading.spi.DomainClassLoader#getPackageNames()
+ */
+ public String[] getPackageNames()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * Find and define the given java class
+ *
+ * @param name - the binary class name
+ * @return the defined Class object
+ * @throws ClassNotFoundException thrown if the class could not be found
+ * or defined
+ */
+ protected Class<?> findClass(String name) throws ClassNotFoundException
+ {
+ String resName = name.replace('.', '/');
+ VirtualFile classFile = findResourceFile(resName+".class");
+ if( classFile == null )
+ throw new ClassNotFoundException(name);
+ try
+ {
+ byte[] tmp = new byte[128];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ InputStream is = classFile.openStream();
+ int length;
+ while ((length = is.read(tmp)) > 0)
+ {
+ baos.write(tmp, 0, length);
+ }
+ is.close();
+ tmp = baos.toByteArray();
+ ProtectionDomain pd = getProtectionDomain(classFile);
+ Class c = super.defineClass(name, tmp, 0, tmp.length, pd);
+ return c;
+ }
+ catch (Exception e)
+ {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+
+ /**
+ * Search for the resource in the VFS contraining the search to the
+ * class loader paths.
+ * @param name - the resource name
+ * @return the resource URL if found, null otherwise
+ */
+ public URL findResource(String name)
+ {
+ URL res = null;
+ VirtualFile vf = findResourceFile(name);
+ if( vf != null )
+ {
+ try
+ {
+ res = vf.toURL();
+ }
+ catch(Exception e)
+ {
+ if( log.isTraceEnabled() )
+ log.trace("Failed to obtain vf URL: "+vf, e);
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Search for the resource in the VFS contraining the search to the
+ * class loader paths.
+ * @param name - the resource name
+ * @return A possibly empty enumeration of the matching resources
+ */
+ public Enumeration<URL> findResources(String name) throws IOException
+ {
+ Vector<URL> resources = new Vector<URL>();
+ /*for(ClassPathVFS cp : classpath)
+ {
+ List<VirtualFile> matches = null;//cp.vfs.resolveFiles(name, cp.searchCtxs);
+ for(VirtualFile vf : matches)
+ {
+ URL resURL = vf.toURL();
+ resources.add(resURL);
+ }
+ }*/
+ return resources.elements();
+ }
+ public Enumeration<URL> findResourcesLocally(String name) throws IOException
+ {
+ return findResources(name);
+ }
+
+ public ClassLoadingDomain getDomain()
+ {
+ return null;
+ }
+ public void setDomain(ClassLoadingDomain domain)
+ {
+ }
+
+ public Class loadClassLocally(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ return findClass(name);
+ }
+
+ public URL loadResourceLocally(String name)
+ {
+ return this.findResource(name);
+ }
+
+ /**
+ * Get the packages defined by the classloader
+ *
+ * @return the packages
+ */
+ public Package[] getPackages()
+ {
+ return super.getPackages();
+ }
+
+ /**
+ * Get a package defined by the classloader
+ *
+ * @param name the name of the package
+ * @return the package
+ */
+ public Package getPackage(String name)
+ {
+ return super.getPackage(name);
+ }
+
+ protected VirtualFile findResourceFile(String name)
+ {
+ VirtualFile vf = null;
+ try
+ {
+ outer:
+ for(ClassPathVFS cp : classpath)
+ {
+ for(String ctx : cp.searchCtxs)
+ {
+ String path = ctx + '/' + name;
+ vf = cp.vfs.findChildFromRoot(path);
+ if( vf != null )
+ {
+ break outer;
+ }
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ if( log.isTraceEnabled() )
+ log.trace("Failed to find resource: "+name, e);
+ }
+ return vf;
+ }
+
+ /**
+ * Determine the protection domain. If we are a copy of the original
+ * deployment, use the original url as the codebase.
+ * @return the protection domain
+ * @throws MalformedURLException
+ * TODO certificates and principles?
+ */
+ protected ProtectionDomain getProtectionDomain(VirtualFile classFile)
+ throws Exception
+ {
+ Certificate certs[] = null;
+ URL codesourceUrl = classFile.toURL();
+ CodeSource cs = new CodeSource(codesourceUrl, certs);
+ PermissionCollection permissions = SecurityActions.getPolicy().getPermissions(cs);
+ if (log.isTraceEnabled())
+ log.trace("getProtectionDomain, url=" + codesourceUrl +
+ " codeSource=" + cs + " permissions=" + permissions);
+ return new ProtectionDomain(cs, permissions);
+ }
+
+ /**
+ * Iterate through the searchCtxs and look for wildcard expressions. Currently only '*.jar' indicating
+ * every jar in a directory is supported.
+ *
+ * @param searchCtxs - input array of vfs paths relative to vfs
+ * @param vfs - the vfs to resolve the searchCtxs against
+ */
+ protected String[] resolveSearchCtxs(String[] searchCtxs, VFS vfs)
+ throws IOException
+ {
+ ArrayList<String> tmp = new ArrayList<String>(searchCtxs.length);
+ for(String ctx : searchCtxs)
+ {
+ if( ctx.endsWith("*.jar") )
+ {
+ // Obtain the parent directory name
+ int slash = ctx.lastIndexOf('/');
+ String dir = "";
+ if( slash > 0 )
+ dir = ctx.substring(0, slash);
+ VirtualFile dirFile = vfs.findChildFromRoot(dir);
+ List<VirtualFile> children = dirFile.getChildren();
+ StringBuilder sb = new StringBuilder(dir);
+ sb.append('/');
+ int dirLength = sb.length();
+ for(VirtualFile child : children)
+ {
+ String name = child.getName();
+ if( name.endsWith(".jar") )
+ {
+ sb.append(name);
+ String path = sb.toString();
+ tmp.add(path);
+ sb.setLength(dirLength);
+ }
+ }
+ }
+ else
+ {
+ tmp.add(ctx);
+ }
+ }
+ log.debug("Resolved searchCtxs to: "+tmp);
+ String[] newCtxs = new String[tmp.size()];
+ tmp.toArray(newCtxs);
+ return newCtxs;
+ }
+}
Added: projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoaderFactory.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoaderFactory.java 2006-09-19 23:25:01 UTC (rev 56981)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/virtual/classloading/VFSClassLoaderFactory.java 2006-09-19 23:50:39 UTC (rev 56982)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.virtual.classloading;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VFS;
+
+/**
+ * A factory for creating VFSClassLoader instances.
+ *
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 55467 $
+ */
+public class VFSClassLoaderFactory
+{
+ private static Logger log = Logger.getLogger(VFSClassLoaderFactory.class);
+
+ public static VFSClassLoader newClassLoader(URI rootURI, String[] paths)
+ throws IOException
+ {
+ log.debug("newClassLoader, rootURI="+rootURI+", paths="+Arrays.asList(paths));
+ VFS vfs = VFS.getVFS(rootURI);
+ return SecurityActions.newClassLoader(paths, vfs);
+ }
+ public static VFSClassLoader newClassLoader(String[] paths, VFS vfs)
+ {
+ log.debug("newClassLoader, vfs="+vfs+", paths="+Arrays.asList(paths));
+ return SecurityActions.newClassLoader(paths, vfs);
+ }
+ public static VFSClassLoader newClassLoader(String[] paths, VFS vfs, ClassLoader parent)
+ {
+ log.debug("newClassLoader, vfs"+vfs+", paths="+Arrays.asList(paths)
+ +", parent="+parent);
+ return SecurityActions.newClassLoader(paths, vfs, parent);
+ }
+}
More information about the jboss-cvs-commits
mailing list