Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   **** BEGIN LICENSE BLOCK *****
   * Version: EPL 1.0/GPL 2.0/LGPL 2.1
   *
   * The contents of this file are subject to the Eclipse Public
   * License Version 1.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.eclipse.org/legal/epl-v10.html
   *
  * Software distributed under the License is distributed on an "AS
  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  * implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the EPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the EPL, the GPL or the LGPL.
  ***** END LICENSE BLOCK *****/
 
 package org.jruby.util;
 
 
 import java.net.URL;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 public class JRubyClassLoader extends URLClassLoader implements ClassDefiningClassLoader {
 
     private static final Logger LOG = LoggerFactory.getLogger("JRubyClassLoader");
 
     private final static ProtectionDomain DEFAULT_DOMAIN;
     
     static {
         ProtectionDomain defaultDomain = null;
         try {
             defaultDomain = JRubyClassLoader.class.getProtectionDomain();
         } catch (SecurityException se) {
             // just use null since we can't acquire protection domain
         }
          = defaultDomain;
     }
 
     private final Map<URL,Set<String>> jarIndexes = new LinkedHashMap<URL,Set<String>>();
 
     private Runnable unloader;
 
     public JRubyClassLoader(ClassLoader parent) {
         super(new URL[0], parent);
     }
 
     // Change visibility so others can see it
     @Override
     public void addURL(URL url) {
         super.addURL(url);
         indexJarContents(url);
     }

    
Called when the parent runtime is torn down.
 
     public void tearDown(boolean debug) {
         try {
             // A hack to allow unloading all JDBC Drivers loaded by this classloader.
             // See http://bugs.jruby.org/4226
             getJDBCDriverUnloader().run();
         } catch (Exception e) {
             if (debug) {
                 .debug(e);
             }
         }
     }
 
     public synchronized Runnable getJDBCDriverUnloader() {
         if ( == null) {
             try {
                InputStream unloaderStream = getClass().getResourceAsStream("/org/jruby/util/JDBCDriverUnloader.class");
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buf = new byte[4096];
                int bytesRead;
                while ((bytesRead = unloaderStream.read(buf)) != -1) {
                    baos.write(buf, 0, bytesRead);
                }
                Class unloaderClass = defineClass("org.jruby.util.JDBCDriverUnloader"baos.toByteArray());
                 = (RunnableunloaderClass.newInstance();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return ;
    }
    public Class<?> defineClass(String namebyte[] bytes) {
        return super.defineClass(namebytes, 0, bytes.length);
     }
    public Class<?> defineClass(String namebyte[] bytesProtectionDomain domain) {
       return super.defineClass(namebytes, 0, bytes.lengthdomain);
    }
    @Override
    protected Class<?> findClass(String classNamethrows ClassNotFoundException {
        try {
            return super.findClass(className);
        } catch (ClassNotFoundException ex) {
            String resourceName = className.replace('.''/').concat(".class");
            URL classUrl = null;
            synchronized () {
                for (URL jarUrl : .keySet()) {
                    if (.get(jarUrl).contains(resourceName)) {
                        try {
                            classUrl = CompoundJarURLStreamHandler.createUrl(jarUrlresourceName);
                            break;
                        } catch (IOException e) {
                            // keep going to next URL
                        }
                    }
                }
            }
            if (classUrl != null) {
                try {
                    InputStream input = classUrl.openStream();
                    try {
                        byte[] buffer = new byte[4096];
                        ByteArrayOutputStream output = new ByteArrayOutputStream();
                        for (int count = input.read(buffer); count > 0; count = input.read(buffer)) {
                            output.write(buffer, 0, count);
                        }
                        byte[] data = output.toByteArray();
                        return defineClass(classNamedata, 0, data.length);
                    } finally {
                        close(input);
                    }
                } catch (IOException e) {
                    // just fall-through to the re-throw below
                }
            }
            throw ex;
        }
    }
    @Override
    public URL findResource(String resourceName) {
        URL result = super.findResource(resourceName);
        if (result == null) {
            synchronized () {
                for (URL jarUrl : .keySet()) {
                    if (.get(jarUrl).contains(resourceName)) {
                        try {
                            return CompoundJarURLStreamHandler.createUrl(jarUrlresourceName);
                        } catch (IOException e) {
                            // keep going
                        }
                    }
                }
            }
        }
        return result;
    }
    @Override
    public Enumeration<URLfindResources(String resourceNamethrows IOException {
        final List<URLembeddedUrls = new ArrayList<URL>();
        synchronized () {
            for (URL jarUrl : .keySet()) {
                if (.get(jarUrl).contains(resourceName)) {
                    try {
                        embeddedUrls.add(CompoundJarURLStreamHandler.createUrl(jarUrlresourceName));
                    } catch (IOException e) {
                        // keep going
                    }
                }
            }
        }
        if (embeddedUrls.isEmpty()) {
            return super.findResources(resourceName);
        } else {
            final Enumeration<URLoriginalResult = super.findResources(resourceName);
            return new Enumeration<URL>() {
                private Iterator<URLextendedResult;
                public URL nextElement() {
                    if ( == null) {
                        return originalResult.nextElement();
                    } else {
                        return .next();
                    }
                }
                public boolean hasMoreElements() {
                    if ( == null) {
                        boolean result = originalResult.hasMoreElements();
                        if (!result) {
                            // original result is consumed, switching to result
                            // from embedded jars processing.
                             = embeddedUrls.iterator();
                            result = .hasNext();
                        }
                        return result;
                    } else {
                        return .hasNext();
                    }
                }
            };
        }
    }
    private void indexJarContents(URL jarUrl) {
        String proto = jarUrl.getProtocol();
        // we only need to index jar: and compoundjar: URLs
        // 1st-level jar files with file: URLs are handled by the JDK
        if (proto.equals("jar") || proto.equals(.)) {
            synchronized () {
                Set<Stringentries = new HashSet<String>();
                .put(jarUrlentries);
                try {
                    InputStream baseInputStream = jarUrl.openStream();
                    try {
                        JarInputStream baseJar = new JarInputStream(baseInputStream);
                        for (JarEntry entry = baseJar.getNextJarEntry(); entry != nullentry = baseJar.getNextJarEntry()) {
                            entries.add(entry.getName());
                        }
                    } finally {
                        close(baseInputStream);
                    }
                } catch (IOException ex) {
                    // can't read the stream, keep going
                }
            }
        }
    }
    private static void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (IOException ignore) {
            }
        }
    }
New to GrepCode? Check out our FAQ X