[Mc4j-cvs] mc4j/modules/ems/src/ems/org/mc4j/ems/connection/support/classloader ClassLoaderFactory.j
Brought to you by:
ghinkl
From: Greg H. <gh...@us...> - 2006-04-12 18:25:39
|
Update of /cvsroot/mc4j/mc4j/modules/ems/src/ems/org/mc4j/ems/connection/support/classloader In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17225/modules/ems/src/ems/org/mc4j/ems/connection/support/classloader Added Files: Tag: ems_module_separation ClassLoaderFactory.java Log Message: no message --- NEW FILE: ClassLoaderFactory.java --- /* * Copyright 2002-2004 Greg Hinkle * * Licensed 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.mc4j.ems.connection.support.classloader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mc4j.ems.connection.EmsConnectException; import org.mc4j.ems.connection.EmsException; import org.mc4j.ems.connection.settings.ConnectionSettings; import org.mc4j.ems.connection.support.metadata.JSR160ConnectionTypeDescriptor; import org.mc4j.ems.connection.support.metadata.WeblogicConnectionTypeDescriptor; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; /** * @author Greg Hinkle (gh...@us...), Apr 5, 2005 * @version $Revision: 1.1.2.5 $($Author: ghinkl $ / $Date: 2006/04/12 18:25:32 $) */ public class ClassLoaderFactory { private static ClassLoaderFactory INSTANCE; private static Log log = LogFactory.getLog(ClassLoaderFactory.class); private static Map<String, File> jarCache = new HashMap<String, File>(); static { String className = System.getProperty("org.mc4j.ems.classloaderfactory"); if (className != null) { try { INSTANCE = ((Class<ClassLoaderFactory>) Class.forName(className)).newInstance(); } catch (Exception e) { throw new EmsException("Unable to load custom classloader factory " + className, e); } } if (INSTANCE == null) { INSTANCE = new ClassLoaderFactory(); } } /** * Retrieves the configured classloader factory for EMS. This can be customized by * setting the system property "org.mc4j.ems.classloaderfactory". * * @return the Classloader Factory used to build the connection classloader */ public static ClassLoaderFactory getInstance() { return INSTANCE; } /** * TODO GH: Implement a special classloader that can load classes from * within a jar inside another jar or perhaps just ship the impl jar separately... */ protected URL storeImplToTemp(String archiveResource) { try { if (jarCache.containsKey(archiveResource)) { return jarCache.get(archiveResource).toURI().toURL(); } InputStream is = ClassLoaderFactory.class.getClassLoader().getResourceAsStream(archiveResource); if (is == null) { throw new EmsException("Unable to find resource to store [" + archiveResource + "]"); } // String tmpPath = System.getProperty("java.io.tmpdir"); String jarName = new File(archiveResource).getName(); jarName = jarName.substring(0, jarName.length() - 4); File tmpFile = File.createTempFile(jarName, ".jar"); tmpFile.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tmpFile); byte[] buffer = new byte[4096]; int size = is.read(buffer); while (size != -1) { fos.write(buffer, 0, size); size = is.read(buffer); } fos.close(); is.close(); jarCache.put(archiveResource, tmpFile); return tmpFile.toURI().toURL(); } catch (FileNotFoundException e) { throw new EmsException("Unable to make temporary file store",e); } catch (IOException e) { throw new EmsException("Unable to make temporary file store",e); } } public ClassLoader buildClassLoader(ConnectionSettings settings) { // TODO GH: Implement configurable system to point at jar instead of creating temporary version List<URL> entries = new ArrayList<URL>(); if (settings.getClassPathEntries() != null) { for (File file : settings.getClassPathEntries()) { try { entries.add(file.toURI().toURL()); } catch (MalformedURLException e) { throw new EmsConnectException("Unable to read class path library url", e); } } } // Now load in the implementation jar // URL implURL = new URL(null, "deepjar://org-mc4j-ems-impl.jar", new Handler()); URL implURL = storeImplToTemp("org-mc4j-ems-impl.jar"); entries.add(implURL); // Add internal support jars for JSR160 on < jdk5 if ((settings.getConnectionType() instanceof JSR160ConnectionTypeDescriptor) && settings.getConnectionType().getConnectionClasspathEntries() == null && Double.parseDouble(System.getProperty("java.version").substring(0, 3)) < 1.5) { entries.add(storeImplToTemp("lib/jsr160-includes/mx4j.jar")); entries.add(storeImplToTemp("lib/jsr160-includes/mx4j-remote.jar")); } // TODO: Check if file exists, log warning if not URL[] entryArray = entries.toArray(new URL[entries.size()]); // TODO - WARNING: GH - DISGUSTING HACK URLClassLoader loader = null; if ((settings.getConnectionType() instanceof WeblogicConnectionTypeDescriptor)) { loader = new ChildFirstClassloader(entryArray, ClassLoaderFactory.class.getClassLoader()); } else { // TODO was NestedJarClassLoader //loader = new ChildFirstClassloader(entryArray, ClassLoaderFactory.class.getClassLoader()); loader = new URLClassLoader(entryArray, ClassLoaderFactory.class.getClassLoader()); //loader = new NestedJarClassLoader(entryArray, ClassLoaderFactory.class.getClassLoader()); } if (log.isDebugEnabled()) { StringBuffer buf = new StringBuffer("Classloader built with: \n"); for (URL url : entries) { buf.append("\t").append(url).append("\n"); } log.debug(buf.toString()); } return loader; } } |