View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.osgi.boot.utils;
20  
21  import java.io.IOException;
22  import java.net.URL;
23  import java.net.URLClassLoader;
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.Enumeration;
27  import java.util.List;
28  
29  import org.eclipse.jetty.util.log.Log;
30  import org.eclipse.jetty.util.log.Logger;
31  import org.osgi.framework.Bundle;
32  
33  /**
34   * OSGiClassLoader
35   *
36   * Class loader that is aware of a bundle. Similar to WebAppClassLoader from Jetty
37   * and the OSGiWebAppClassLoader, but works without webapps.
38   */
39  public class OSGiClassLoader extends URLClassLoader
40  {
41      private static final Logger LOG = Log.getLogger(OSGiClassLoader.class);
42      
43      
44      private Bundle _bundle;
45      private ClassLoader _osgiBundleClassLoader;
46      private boolean _lookInOsgiFirst = true;
47      private ClassLoader _parent;
48      
49      /* ------------------------------------------------------------ */
50      public OSGiClassLoader(ClassLoader parent, Bundle bundle)
51      {
52          super(new URL[]{}, parent);
53          _parent = getParent();
54          _bundle = bundle;
55          _osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(_bundle);
56      }
57      
58    
59      
60      /* ------------------------------------------------------------ */
61      /**
62       * Get a resource from the classloader
63       * 
64       * Copied from WebAppClassLoader
65       */
66      public URL getResource(String name)
67      {
68          URL url= null;
69          boolean tried_parent= false;
70  
71          
72          if (_parent!=null && !_lookInOsgiFirst)
73          {
74              tried_parent= true;
75              
76              if (_parent!=null)
77                  url= _parent.getResource(name);
78          }
79  
80          if (url == null)
81          {           
82              url = _osgiBundleClassLoader.getResource(name);
83  
84              if (url == null && name.startsWith("/"))
85              {
86                  if (LOG.isDebugEnabled())
87                      LOG.debug("HACK leading / off " + name);
88  
89                  url = _osgiBundleClassLoader.getResource(name.substring(1));
90              }
91          }
92  
93          if (url == null && !tried_parent)
94          {
95              if (_parent!=null)
96                  url= _parent.getResource(name);
97          }
98  
99          if (url != null)
100             if (LOG.isDebugEnabled())
101                 LOG.debug("getResource("+name+")=" + url);
102 
103         return url;
104     }
105     
106     /* ------------------------------------------------------------ */
107     @Override
108     public Class<?> loadClass(String name) throws ClassNotFoundException
109     {
110         return loadClass(name, false);
111     }
112 
113     /* ------------------------------------------------------------ */
114     @Override
115     protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
116     {
117         Class<?> c = findLoadedClass(name);
118         ClassNotFoundException ex= null;
119         boolean tried_parent= false;
120         
121         if (c == null && _parent!=null && !_lookInOsgiFirst)
122         {
123             tried_parent= true;
124             try
125             {
126                 c= _parent.loadClass(name);
127                 if (LOG.isDebugEnabled())
128                     LOG.debug("loaded " + c);
129             }
130             catch (ClassNotFoundException e)
131             {
132                 ex= e;
133             }
134         }
135 
136         if (c == null)
137         {
138             try
139             {
140                 c= this.findClass(name);
141             }
142             catch (ClassNotFoundException e)
143             {
144                 ex= e;
145             }
146         }
147 
148         if (c == null && _parent!=null && !tried_parent)
149             c = _parent.loadClass(name);
150 
151         if (c == null)
152             throw ex;
153 
154         if (resolve)
155             resolveClass(c);
156 
157         if (LOG.isDebugEnabled())
158             LOG.debug("loaded " + c+ " from "+c.getClassLoader());
159         
160         return c;
161     }
162     
163     /* ------------------------------------------------------------ */
164     @Override
165     public Enumeration<URL> getResources(String name) throws IOException
166     {
167         Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
168         Enumeration<URL> urls = super.getResources(name);
169         if (_lookInOsgiFirst)
170         {
171             return Collections.enumeration(toList(osgiUrls, urls));
172         }
173         else
174         {
175             return Collections.enumeration(toList(urls, osgiUrls));
176         }
177     }
178     
179     
180     /* ------------------------------------------------------------ */
181     @Override
182     protected Class<?> findClass(String name) throws ClassNotFoundException
183     {
184         try
185         {
186             return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
187         }
188         catch (ClassNotFoundException cne)
189         {
190             try
191             {
192                 return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
193             }
194             catch (ClassNotFoundException cne2)
195             {
196                 throw cne;
197             }
198         }
199     }
200     
201     
202     
203     
204 
205    /* ------------------------------------------------------------ */
206     /**
207      * @param e
208      * @param e2
209      * @return
210      */
211     private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
212     {
213         List<URL> list = new ArrayList<URL>();
214         while (e != null && e.hasMoreElements())
215             list.add(e.nextElement());
216         while (e2 != null && e2.hasMoreElements())
217             list.add(e2.nextElement());
218         return list;
219     }
220 }