View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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              
83              url = _osgiBundleClassLoader.getResource(name);
84  
85              if (url == null && name.startsWith("/"))
86              {
87                  if (LOG.isDebugEnabled())
88                      LOG.debug("HACK leading / off " + name);
89  
90                  url = _osgiBundleClassLoader.getResource(name.substring(1));
91              }
92          }
93  
94          if (url == null && !tried_parent)
95          {
96              if (_parent!=null)
97                  url= _parent.getResource(name);
98          }
99  
100         if (url != null)
101             if (LOG.isDebugEnabled())
102                 LOG.debug("getResource("+name+")=" + url);
103 
104         return url;
105     }
106     
107     /* ------------------------------------------------------------ */
108     @Override
109     public Class<?> loadClass(String name) throws ClassNotFoundException
110     {
111         return loadClass(name, false);
112     }
113 
114     /* ------------------------------------------------------------ */
115     @Override
116     protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
117     {
118         Class<?> c = findLoadedClass(name);
119         ClassNotFoundException ex= null;
120         boolean tried_parent= false;
121         
122         if (c == null && _parent!=null && !_lookInOsgiFirst)
123         {
124             tried_parent= true;
125             try
126             {
127                 c= _parent.loadClass(name);
128                 if (LOG.isDebugEnabled())
129                     LOG.debug("loaded " + c);
130             }
131             catch (ClassNotFoundException e)
132             {
133                 ex= e;
134             }
135         }
136 
137         if (c == null)
138         {
139             try
140             {
141                 c= this.findClass(name);
142             }
143             catch (ClassNotFoundException e)
144             {
145                 ex= e;
146             }
147         }
148 
149         if (c == null && _parent!=null && !tried_parent)
150             c = _parent.loadClass(name);
151 
152         if (c == null)
153             throw ex;
154 
155         if (resolve)
156             resolveClass(c);
157 
158         if (LOG.isDebugEnabled())
159             LOG.debug("loaded " + c+ " from "+c.getClassLoader());
160         
161         return c;
162     }
163     
164     /* ------------------------------------------------------------ */
165     @Override
166     public Enumeration<URL> getResources(String name) throws IOException
167     {
168         Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
169         Enumeration<URL> urls = super.getResources(name);
170         if (_lookInOsgiFirst)
171         {
172             return Collections.enumeration(toList(osgiUrls, urls));
173         }
174         else
175         {
176             return Collections.enumeration(toList(urls, osgiUrls));
177         }
178     }
179     
180     
181     /* ------------------------------------------------------------ */
182     @Override
183     protected Class<?> findClass(String name) throws ClassNotFoundException
184     {
185         try
186         {
187             return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
188         }
189         catch (ClassNotFoundException cne)
190         {
191             try
192             {
193                 return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
194             }
195             catch (ClassNotFoundException cne2)
196             {
197                 throw cne;
198             }
199         }
200     }
201     
202     
203     
204     
205 
206    /* ------------------------------------------------------------ */
207     /**
208      * @param e
209      * @param e2
210      * @return
211      */
212     private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
213     {
214         List<URL> list = new ArrayList<URL>();
215         while (e != null && e.hasMoreElements())
216             list.add(e.nextElement());
217         while (e2 != null && e2.hasMoreElements())
218             list.add(e2.nextElement());
219         return list;
220     }
221 }