Source Code Cross Referenced for StickyClassLoader.java in  » IDE » DrJava » edu » rice » cs » util » classloader » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.util.classloader 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.util.classloader;
038:
039:        import java.util.Arrays;
040:        import java.net.URL;
041:        import java.io.IOException;
042:        import java.io.InputStream;
043:
044:        import edu.rice.cs.plt.io.IOUtil;
045:        import edu.rice.cs.util.FileOps;
046:
047:        /** A {@link ClassLoader} that works as the union of two classloaders, but always tries to delegate to the first of 
048:         *  these.  The purpose for this class is to ensure that classes loaded transitively due to some class's loading are
049:         *  also loaded with the right classloader. Here's the problem: Say that class A contains a reference to class B, but
050:         *  the specific B is unknown to clients of class A. Class A is loadable by the standard classloader, but class B needs
051:         *  to be loaded with a (known) custom classloader.
052:         *  <P>
053:         *  If A were loaded using the standard classloader, it would fail because this would cause the transitive loading of 
054:         *  B to be done by the system loader as well.  If A were loaded with the custom loader, the same thing would happen --
055:         *  the custom loader would delegate to the system loader to load A (since it doesn't load non-custom-loader-requiring 
056:         *  classes), but this would associate class A with the system classloader. (Every class is associated with the loader 
057:         *  that called {@link ClassLoader#defineClass} to define it in the JVM.) This association would make B be loaded by 
058:         *  the standard loader!
059:         *  <P>
060:         *  To get around this problem, we use this class, which acts mostly as a union of two classloaders. The trick, however, 
061:         *  is that the StickyClassLoader has itself associated with all classes it loads, even though the actual work is done 
062:         *  by the two loaders it delegates to.  (It does this by calling {@link ClassLoader#findResource} on the subordinate 
063:         *  loaders to get the class data, but then by calling {@link ClassLoader#defineClass} itself to preserve the 
064:         *  association.
065:         *
066:         *  @version $Id: StickyClassLoader.java 4255 2007-08-28 19:17:37Z mgricken $
067:         */
068:        public class StickyClassLoader extends ClassLoader {
069:            private final ClassLoader _newLoader;
070:            private final String[] _classesToLoadWithOld;
071:
072:            /** Creates a sticky class loader with the given primary and secondary loaders to join together. All classes will be 
073:             *  attempted to be loaded with the primary loader, and the secondary will be used as a fallback.
074:             *  @param newLoader Primary loader
075:             *  @param oldLoader Secondary loader
076:             */
077:            public StickyClassLoader(final ClassLoader newLoader,
078:                    final ClassLoader oldLoader) {
079:                this (newLoader, oldLoader, new String[0]);
080:            }
081:
082:            /** Creates a sticky class loader with the given primary and secondary loaders to join together. All classes will be
083:             * attempted to be loaded with the primary loader
084:             * (except for classes in <code>classesToLoadWithOld</code>),
085:             * and the secondary will be used as a fallback.
086:             *
087:             * @param newLoader Primary loader
088:             * @param oldLoader Secondary loader
089:             * @param classesToLoadWithOld All class names in this array will be loaded only with the secondary classloader. This
090:             *        is vital to ensure that only one copy of some classes are loaded, since two differently loaded versions of
091:             *        a class act totally independently! (That is, they have different, incompatible types.) Often it'll be 
092:             *        necessary to make key interfaces that are used between components get loaded via one standard classloader, 
093:             *        to ensure that things can be cast to that interface.
094:             */
095:            public StickyClassLoader(final ClassLoader newLoader,
096:                    final ClassLoader oldLoader,
097:                    final String[] classesToLoadWithOld) {
098:                super (oldLoader);
099:                _newLoader = newLoader; // to be used only in getResource()!
100:                _classesToLoadWithOld = new String[classesToLoadWithOld.length];
101:                System.arraycopy(classesToLoadWithOld, 0,
102:                        _classesToLoadWithOld, 0, classesToLoadWithOld.length);
103:                Arrays.sort(_classesToLoadWithOld);
104:            }
105:
106:            /** Gets the requested resource, looking first in the new loader and then in the old loader.
107:             *  @param name Name of resource to find
108:             *  @return URL of the resource if found/accessible, or null if not.
109:             */
110:            public URL getResource(String name) {
111:                URL resource = _newLoader.getResource(name);
112:                if (resource == null)
113:                    resource = getParent().getResource(name);
114:
115:                //System.err.println("resource: " + name + " --> " + resource);
116:                return resource;
117:            }
118:
119:            /** Loads the given class, delegating first to the new class loader and then second to the old class loader. The 
120:             *  returned Class object will have its ClassLoader ({@link Class#getClassLoader}) set to be this. This is very
121:             *  important because it causes classes that are loaded due to this class  being loaded (ancestor classes/interfaces,
122:             *  referenced classes, etc) to use the same loader.  There are a few exceptions to this explanation:
123:             *  <OL>
124:             *  <LI>If the class is in java.* or javax.*, it will be loaded using {@link ClassLoader#getSystemClassLoader}. This 
125:             *      is because only the system loader is allowed to load system classes!  Also: sun.*.
126:             *  </LI>
127:             *  <LI>If the class name is in the list of classes to load with the old class loader (passed to constructor), the new
128:             *      loader is not considered when trying to load the class.  This is useful to make sure that certain classes (or 
129:             *      interfaces) only have one copy in the system, to ensure that you can cast to that
130:             *      class/interface regardless of which loader loaded the other class.
131:             *  </LI>
132:             *  </OL>
133:             */
134:            protected Class<?> loadClass(String name, boolean resolve)
135:                    throws ClassNotFoundException {
136:                // check if it's already loaded in the JVM!
137:                Class<?> clazz;
138:                clazz = findLoadedClass(name);
139:                if (clazz != null)
140:                    return clazz;
141:
142:                if (name.startsWith("java.") || name.startsWith("javax.")
143:                        || name.startsWith("sun.")
144:                        || name.startsWith("com.sun.")
145:                        || name.startsWith("org.omg.")
146:                        || name.startsWith("sunw.")
147:                        || name.startsWith("org.w3c.dom.")
148:                        || name.startsWith("org.xml.sax.")
149:                        || name.startsWith("net.jini.")) {
150:
151:                    try {
152:                        clazz = getSystemClassLoader().loadClass(name);
153:                    } catch (ClassNotFoundException e) {
154:                        // It might be a non-system class, like javax.mail.*.
155:                        //  Fall back on the secondary loader.
156:                        clazz = _loadWithSecondary(name);
157:                    }
158:                } else if (Arrays.binarySearch(_classesToLoadWithOld, name) >= 0) {
159:                    // Don't fall back to secondary if this fails...
160:                    clazz = getParent().loadClass(name);
161:                } else {
162:                    // Load with the secondary loader
163:                    clazz = _loadWithSecondary(name);
164:                    // If this fails don't fall back to loading with oldClassloader (or, 
165:                    // equivalently, getParent()) cuz getResource() (called by _loadWithSecondary())
166:                    // calls getParent.getResource() if _newLoader.getResource() returns null
167:                }
168:
169:                if (resolve)
170:                    resolveClass(clazz);
171:
172:                //    System.out.println("Sticky loaded OK: " + name + " " + clazz + " loader=" + clazz.getClassLoader());
173:                return clazz;
174:            }
175:
176:            /** Try to load the class with the given name with the secondary (new) loader. Uses getResource to find the class.
177:             *  @param name Name of the class to load.
178:             */
179:            protected Class _loadWithSecondary(String name)
180:                    throws ClassNotFoundException {
181:                // we get the data using getResource because if we just delegate
182:                // the call to loadClass on old or new loader, it will use that
183:                // loader as the associated class loader for the class. that's bad.
184:                // The method does not depend on the newLoader except indirectly
185:                // in the call to getResource()
186:                try {
187:                    String fileName = name.replace('.', '/') + ".class";
188:
189:                    URL resource = getResource(fileName); // only dependency on newLoader!
190:                    if (resource == null) {
191:                        throw new ClassNotFoundException("Resource not found: "
192:                                + fileName);
193:                    }
194:
195:                    InputStream in = resource.openStream();
196:                    try {
197:                        byte[] data = IOUtil.toByteArray(in);
198:                        return defineClass(name, data, 0, data.length);
199:                    } finally {
200:                        in.close();
201:                    }
202:                } catch (IOException ioe) {
203:                    throw new ClassNotFoundException(ioe.toString());
204:                }
205:            }
206:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.