Source Code Cross Referenced for EngineClassLoader.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » engine » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.engine 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003:         * Distributed under the terms of either:
0004:         * - the common development and distribution license (CDDL), v1.0; or
0005:         * - the GNU Lesser General Public License, v2.1 or later
0006:         * $Id: EngineClassLoader.java 3862 2007-07-13 14:37:11Z gbevin $
0007:         */
0008:        package com.uwyn.rife.engine;
0009:
0010:        import com.tc.object.loaders.NamedClassLoader;
0011:        import com.uwyn.rife.engine.instrument.ElementDetector;
0012:        import com.uwyn.rife.instrument.ClassBytesProvider;
0013:        import com.uwyn.rife.instrument.exceptions.ClassBytesNotFoundException;
0014:        import com.uwyn.rife.resources.ModificationTimeClasspath;
0015:        import com.uwyn.rife.site.instrument.ConstrainedDetector;
0016:        import com.uwyn.rife.tools.ClassBytesLoader;
0017:        import com.uwyn.rife.tools.FileUtils;
0018:        import com.uwyn.rife.tools.InstrumentationUtils;
0019:        import java.io.File;
0020:        import java.io.UnsupportedEncodingException;
0021:        import java.lang.reflect.Constructor;
0022:        import java.lang.reflect.Field;
0023:        import java.lang.reflect.InvocationTargetException;
0024:        import java.lang.reflect.Method;
0025:        import java.net.URL;
0026:        import java.net.URLClassLoader;
0027:        import java.net.URLDecoder;
0028:        import java.util.ArrayList;
0029:        import java.util.HashMap;
0030:        import java.util.HashSet;
0031:        import java.util.List;
0032:        import java.util.Set;
0033:
0034:        public class EngineClassLoader extends URLClassLoader implements 
0035:                NamedClassLoader, ClassBytesProvider {
0036:            public final static String DEFAULT_IMPLEMENTATIONS_PATH = "implementations/";
0037:            public final static String META_DATA_SUFFIX = "MetaData";
0038:
0039:            private static HashMap<String, Long> sModificationTimes = new HashMap<String, Long>();
0040:
0041:            private static List<String> sRifeWebappPath = null;
0042:            private static boolean sRifeWebappPathProcessed = false;
0043:
0044:            private Set<String> mModifiedClasses = null;
0045:            private boolean mIsParentEngineclassloader = false;
0046:            private EngineClassLoader mChild = null;
0047:            private ClassLoader mInitiating = null;
0048:
0049:            private Method mFindLoadedClassMethod = null;
0050:
0051:            private ClassBytesLoader mByteLoader = null;
0052:
0053:            private ElementDetector mElementDetector = null;
0054:            private ConstrainedDetector mConstrainedDetector = null;
0055:
0056:            private Class mMergerClass = null;
0057:            private Method mMergerMethod = null;
0058:
0059:            private Class mLazyLoadClass = null;
0060:            private Method mLazyLoadMethod = null;
0061:
0062:            private Object mEngineContinuationConfigInstrument = null;
0063:
0064:            private Class mContinuationConfigInstrumentClass = null;
0065:
0066:            private Class mResumerClass = null;
0067:            private Method mResumerMethod = null;
0068:
0069:            private String mClassLoaderName = "RIFE:EngineClassLoader";
0070:
0071:            public EngineClassLoader(ClassLoader parent) {
0072:                super (new URL[0], parent);
0073:
0074:                // check for the presence of Terracotta by loading its ClassProcessorHelper class
0075:                try {
0076:                    Class classprocessor_helper_class = Class
0077:                            .forName("com.tc.object.bytecode.hook.impl.ClassProcessorHelper");
0078:                    if (classprocessor_helper_class != null) {
0079:                        if (parent instanceof  NamedClassLoader) {
0080:                            NamedClassLoader namedParent = (NamedClassLoader) parent;
0081:                            mClassLoaderName = "Rife:Engine:"
0082:                                    + namedParent.__tc_getClassLoaderName();
0083:
0084:                            try {
0085:                                Method method = classprocessor_helper_class
0086:                                        .getDeclaredMethod(
0087:                                                "registerGlobalLoader",
0088:                                                new Class[] { NamedClassLoader.class });
0089:                                method.invoke(null, new Object[] { this  });
0090:                            } catch (Exception e) {
0091:                                throw new RuntimeException(
0092:                                        "Unable to register the engine classloader '"
0093:                                                + mClassLoaderName
0094:                                                + "' with Terracotta.", e);
0095:                            }
0096:                        }
0097:                    }
0098:                } catch (ClassNotFoundException e) {
0099:                    // this is OK, Terracotta is not present in the classpath
0100:                }
0101:
0102:                mIsParentEngineclassloader = parent instanceof  EngineClassLoader;
0103:                if (mIsParentEngineclassloader) {
0104:                    mInitiating = ((EngineClassLoader) parent).mInitiating;
0105:                } else {
0106:                    mInitiating = parent;
0107:                }
0108:
0109:                mByteLoader = new ClassBytesLoader(this );
0110:                mByteLoader.setupSunByteLoading();
0111:                if (mByteLoader.isUsingSunByteLoading()) {
0112:                    addClassPathURLs();
0113:                }
0114:
0115:                mElementDetector = new ElementDetector(this );
0116:
0117:                mConstrainedDetector = new ConstrainedDetector(mByteLoader);
0118:            }
0119:
0120:            public String __tc_getClassLoaderName() {
0121:                return mClassLoaderName;
0122:            }
0123:
0124:            public void __tc_setClassLoaderName(String name) {
0125:                throw new UnsupportedOperationException(
0126:                        "class loader name can not be modified for loader with name: "
0127:                                + mClassLoaderName);
0128:            }
0129:
0130:            private void addClassPathURLs() {
0131:                try {
0132:                    Class classpathutils_class = loadClass("com.uwyn.rife.tools.ClasspathUtils");
0133:                    Method classpathutils_method = classpathutils_class
0134:                            .getDeclaredMethod("getClassPathAsList",
0135:                                    Class.class);
0136:                    List<String> classpath = (List<String>) classpathutils_method
0137:                            .invoke(null, getClass());
0138:                    if (classpath != null) {
0139:                        for (String classpath_element : classpath) {
0140:                            addURL(new URL("file", null, classpath_element));
0141:                        }
0142:                    }
0143:                } catch (Throwable e) {
0144:                    throw new RuntimeException(e);
0145:                }
0146:            }
0147:
0148:            private boolean containsModifiedClass(String classname) {
0149:                if (null == mModifiedClasses) {
0150:                    return false;
0151:                }
0152:
0153:                if (mModifiedClasses.contains(classname)) {
0154:                    return true;
0155:                }
0156:
0157:                int innerclass_index = classname.indexOf("$");
0158:                if (innerclass_index != -1) {
0159:                    String containing_classname = classname.substring(0,
0160:                            innerclass_index);
0161:                    if (mModifiedClasses.contains(containing_classname)) {
0162:                        return true;
0163:                    }
0164:                }
0165:
0166:                return false;
0167:            }
0168:
0169:            protected Class loadClass(String classname, boolean resolve)
0170:                    throws ClassNotFoundException {
0171:                return loadClass(classname, resolve, false);
0172:            }
0173:
0174:            synchronized public void markClassAsModified(String classname) {
0175:                if (null == mModifiedClasses) {
0176:                    mModifiedClasses = new HashSet<String>();
0177:                }
0178:
0179:                if (mChild != null && mModifiedClasses.contains(classname)) {
0180:                    mChild.markClassAsModified(classname);
0181:                } else {
0182:                    if (null == mChild) {
0183:                        mChild = new EngineClassLoader(this );
0184:                    }
0185:                    mModifiedClasses.add(classname);
0186:                }
0187:            }
0188:
0189:            public Class loadClass(String classname, boolean resolve,
0190:                    boolean loadElement) throws ClassNotFoundException {
0191:                assert classname != null;
0192:
0193:                //		System.out.println(">>> "+classname);
0194:
0195:                // get the auto reload preferences
0196:                boolean auto_reload = doAutoReload();
0197:
0198:                // see if this classloader has cached the class with the provided name
0199:                Class c = null;
0200:                if (auto_reload && containsModifiedClass(classname)) {
0201:                    return mChild.loadClass(classname, resolve, loadElement);
0202:                }
0203:                if (null == c) {
0204:                    c = findLoadedClass(classname);
0205:                }
0206:
0207:                // if an already loaded version was found, check whether it's outdated or not
0208:                if (c != null) {
0209:                    // if an already loaded version was found, check whether it's outdated or not
0210:                    // this can only be Element classes since those are the only ones that are
0211:                    // handled by this classloader
0212:                    if (auto_reload) {
0213:                        // if the element was modified, don't use the cached class
0214:                        // otherwise, just take the previous element class
0215:                        if (loadElement && isModified(classname)) {
0216:                            synchronized (this ) {
0217:                                markClassAsModified(classname);
0218:
0219:                                Class klass = mChild.loadClass(classname,
0220:                                        resolve, loadElement);
0221:                                clearSiteCaches(classname);
0222:                                return klass;
0223:                            }
0224:                        }
0225:                    }
0226:                }
0227:                // try to obtain the class in another way
0228:                else {
0229:                    // try to load the core system classes first, these are sure to be
0230:                    // handled by the system classloader
0231:                    if (null == c) {
0232:                        if (classname.startsWith("java.")) {
0233:                            try {
0234:                                c = findSystemClass(classname);
0235:                                if (c != null) {
0236:                                    if (resolve) {
0237:                                        resolveClass(c);
0238:                                    }
0239:
0240:                                    //							System.out.println("SYSTEM defined "+classname);
0241:
0242:                                    return c;
0243:                                }
0244:                            } catch (ClassNotFoundException e) {
0245:                                c = null;
0246:                            }
0247:                        }
0248:                    }
0249:
0250:                    ClassLoader parent = getParent();
0251:                    classname = classname.intern();
0252:
0253:                    // Get classes already loaded by the servlet container's classloader,
0254:                    // to avoid loading them again. These will be classes loaded by other
0255:                    // filters and listeners inside the same web application, initialized
0256:                    // before RIFE. For RIFE these should only be the
0257:                    // EngineClassLoader-related classed and those of the continuations engine
0258:                    try {
0259:                        if (null == mFindLoadedClassMethod) {
0260:                            mFindLoadedClassMethod = ClassLoader.class
0261:                                    .getDeclaredMethod(
0262:                                            "findLoadedClass",
0263:                                            new Class[] { java.lang.String.class });
0264:                            mFindLoadedClassMethod.setAccessible(true);
0265:                        }
0266:
0267:                        c = (Class) mFindLoadedClassMethod.invoke(mInitiating,
0268:                                (Object[]) new String[] { classname });
0269:                        //				if (c != null)
0270:                        //				{
0271:                        //					System.out.println("PARENT defined "+classname+" (already loaded)");
0272:                        //				}
0273:                    } catch (Throwable e) {
0274:                        c = null;
0275:                    }
0276:
0277:                    // load the class through the initial EngineClassLoader, unless it
0278:                    // has been modified
0279:                    if (mIsParentEngineclassloader
0280:                            && !((EngineClassLoader) parent)
0281:                                    .containsModifiedClass(classname)) {
0282:                        //				if (c != null)
0283:                        //				{
0284:                        //					System.out.println("PARENT loading "+classname);
0285:                        //				}
0286:                        return ((EngineClassLoader) parent).loadClass(
0287:                                classname, resolve, loadElement);
0288:                    }
0289:
0290:                    // try to obtain the class in a RIFE-specific way
0291:                    if (null == c
0292:                            && !classname.startsWith("com.uwyn.rife.asm.")
0293:                            && !classname.startsWith("com.tc.object.loaders.")) {
0294:                        boolean webapp_class = false;
0295:                        boolean rife_class = false;
0296:                        if (classname == "com.uwyn.rife.engine.EngineClassLoaderRifeWebappPath") {
0297:                            webapp_class = true;
0298:                        } else {
0299:                            // This is not a problem, if several simultaneous threads
0300:                            // will access it, it will just be retrieved several times.
0301:                            // The calls will be cached for all subsequent threads
0302:                            // though.
0303:                            if (!sRifeWebappPathProcessed) {
0304:                                try {
0305:                                    Class webapp_path_class = loadClass("com.uwyn.rife.engine.EngineClassLoaderRifeWebappPath");
0306:                                    Field webapp_path_field = webapp_path_class
0307:                                            .getField("RIFE_WEBAPP_PATH");
0308:                                    sRifeWebappPath = (ArrayList<String>) webapp_path_field
0309:                                            .get(null);
0310:                                    sRifeWebappPathProcessed = true;
0311:                                } catch (Throwable e) {
0312:                                    throw new ClassNotFoundException(classname,
0313:                                            e);
0314:                                }
0315:                            }
0316:
0317:                            // check of the class is part of the web application, or if it should be loaded through
0318:                            // a parent classloader
0319:                            if (classname.startsWith("com.uwyn.rife.")) // classes are loaded by the EngineClassLoader
0320:                            {
0321:                                webapp_class = true;
0322:                                rife_class = true;
0323:                            } else {
0324:                                webapp_class = isWebAppClass(classname);
0325:                            }
0326:
0327:                            // only handle undefined classes, or check existing ones if
0328:                            // auto-reloading has been activated
0329:                            if (null == c || auto_reload) {
0330:                                String packagename = null;
0331:                                int packagename_index = classname
0332:                                        .lastIndexOf('.');
0333:                                if (packagename_index != -1) {
0334:                                    packagename = classname.substring(0,
0335:                                            packagename_index);
0336:                                }
0337:
0338:                                // first try to find the compiled bytecode, take inner classes
0339:                                // into account
0340:                                byte raw_bytes[] = null;
0341:                                int innerclass_index = classname.indexOf("$");
0342:                                try {
0343:                                    if (innerclass_index > -1) {
0344:                                        raw_bytes = getClassBytes(
0345:                                                classname.substring(0,
0346:                                                        innerclass_index),
0347:                                                auto_reload, loadElement);
0348:                                    } else {
0349:                                        raw_bytes = getClassBytes(classname,
0350:                                                auto_reload, loadElement);
0351:                                    }
0352:                                } catch (ClassNotFoundException e) {
0353:                                    raw_bytes = null;
0354:                                }
0355:
0356:                                if (raw_bytes != null) {
0357:                                    // check if the bytes corresponds to an element class
0358:                                    if (!isElement(classname, raw_bytes,
0359:                                            auto_reload)) {
0360:                                        // If it's not an element and the class hasn't been
0361:                                        // defined yet, define it. If it has been found in the
0362:                                        // parent, use the already existing instance.
0363:                                        // Auto-reloading isn't supported for non-elements
0364:                                        if (null == c) {
0365:                                            if (!webapp_class) {
0366:                                                try {
0367:                                                    //											System.out.println("PARENT defined "+classname+" (not webapp class)");
0368:                                                    if (!mIsParentEngineclassloader) {
0369:                                                        c = parent
0370:                                                                .loadClass(classname);
0371:                                                    }
0372:                                                } catch (ClassNotFoundException e) {
0373:                                                    c = null;
0374:                                                }
0375:                                            } else {
0376:                                                //										System.out.println("ENGINE defined "+classname);
0377:
0378:                                                if (packagename != null) {
0379:                                                    Package pkg = getPackage(packagename);
0380:                                                    if (null == pkg) {
0381:                                                        definePackage(
0382:                                                                packagename,
0383:                                                                null, null,
0384:                                                                null, null,
0385:                                                                null, null,
0386:                                                                null);
0387:                                                    }
0388:                                                }
0389:
0390:                                                // use the interned classname to get a synchronization lock monitor
0391:                                                // that is specific for the current class that is loaded and
0392:                                                // that will not lock up the classloading of all other classes
0393:                                                // by for instance synchronizing on this classloader
0394:                                                synchronized (classname) {
0395:                                                    // make sure that the class has not been defined in the
0396:                                                    // meantime, otherwise defining it again will trigger an
0397:                                                    // exception;
0398:                                                    // reuse the existing class if it has already been defined
0399:                                                    c = findLoadedClass(classname);
0400:                                                    if (null == c) {
0401:                                                        // if we are working with an inner class, get its
0402:                                                        // actual raw bytes, since we used the containing
0403:                                                        // class's bytes to determine if it's an element
0404:                                                        if (innerclass_index > -1) {
0405:                                                            raw_bytes = getClassBytes(
0406:                                                                    classname,
0407:                                                                    auto_reload,
0408:                                                                    loadElement);
0409:                                                        }
0410:
0411:                                                        if (!rife_class) {
0412:                                                            // handle meta data sibling classes for non framework classes
0413:                                                            Class metadata_class = null;
0414:                                                            if (!classname
0415:                                                                    .endsWith(META_DATA_SUFFIX)) {
0416:                                                                try {
0417:                                                                    metadata_class = loadClass(classname
0418:                                                                            + META_DATA_SUFFIX);
0419:                                                                } catch (ClassNotFoundException e) {
0420:                                                                    metadata_class = null;
0421:                                                                }
0422:
0423:                                                                if (metadata_class != null) {
0424:                                                                    if (null == mMergerClass) {
0425:                                                                        mMergerClass = loadClass("com.uwyn.rife.site.instrument.MetaDataBytecodeTransformer");
0426:                                                                    }
0427:
0428:                                                                    try {
0429:                                                                        if (null == mMergerMethod) {
0430:                                                                            mMergerMethod = mMergerClass
0431:                                                                                    .getDeclaredMethod(
0432:                                                                                            "mergeMetaDataIntoBytes",
0433:                                                                                            new Class[] {
0434:                                                                                                    byte[].class,
0435:                                                                                                    Class.class });
0436:                                                                            mMergerMethod
0437:                                                                                    .setAccessible(true);
0438:                                                                        }
0439:                                                                        raw_bytes = (byte[]) mMergerMethod
0440:                                                                                .invoke(
0441:                                                                                        null,
0442:                                                                                        new Object[] {
0443:                                                                                                raw_bytes,
0444:                                                                                                metadata_class });
0445:                                                                    } catch (Exception e) {
0446:                                                                        throw new ClassNotFoundException(
0447:                                                                                classname,
0448:                                                                                e);
0449:                                                                    }
0450:                                                                }
0451:                                                            }
0452:
0453:                                                            try {
0454:                                                                if (isConstrained(
0455:                                                                        classname,
0456:                                                                        raw_bytes)) {
0457:                                                                    // handle lazy loading for constrained non framework classes
0458:                                                                    if (null == mLazyLoadClass) {
0459:                                                                        mLazyLoadClass = loadClass("com.uwyn.rife.database.querymanagers.generic.instrument.LazyLoadAccessorsBytecodeTransformer");
0460:                                                                    }
0461:
0462:                                                                    if (null == mLazyLoadMethod) {
0463:                                                                        mLazyLoadMethod = mLazyLoadClass
0464:                                                                                .getDeclaredMethod(
0465:                                                                                        "addLazyLoadToBytes",
0466:                                                                                        new Class[] { byte[].class });
0467:                                                                        mLazyLoadMethod
0468:                                                                                .setAccessible(true);
0469:                                                                    }
0470:                                                                    raw_bytes = (byte[]) mLazyLoadMethod
0471:                                                                            .invoke(
0472:                                                                                    null,
0473:                                                                                    new Object[] { raw_bytes });
0474:                                                                }
0475:                                                            } catch (Exception e) {
0476:                                                                throw new ClassNotFoundException(
0477:                                                                        classname,
0478:                                                                        e);
0479:                                                            }
0480:                                                        }
0481:
0482:                                                        // define the class from its raw bytes
0483:                                                        InstrumentationUtils
0484:                                                                .dumpClassBytes(
0485:                                                                        "adapted",
0486:                                                                        classname,
0487:                                                                        raw_bytes);
0488:                                                        c = defineClass(
0489:                                                                classname,
0490:                                                                raw_bytes,
0491:                                                                0,
0492:                                                                raw_bytes.length);
0493:
0494:                                                        if (null == c) {
0495:                                                            throw new ClassNotFoundException(
0496:                                                                    classname);
0497:                                                        }
0498:                                                    }
0499:                                                }
0500:                                            }
0501:                                        }
0502:                                    } else {
0503:                                        //								if (null == c)
0504:                                        //								{
0505:                                        //									System.out.println("ENGINE defined "+classname);
0506:                                        //								}
0507:                                        //								else
0508:                                        //								{
0509:                                        //									System.out.println("ENGINE redefined "+classname);
0510:                                        //								}
0511:
0512:                                        // if we are working with an inner class, get its
0513:                                        // actual raw bytes, since we used the containing
0514:                                        // class's bytes to determine if it's an element
0515:                                        if (innerclass_index > -1) {
0516:                                            raw_bytes = getClassBytes(
0517:                                                    classname, auto_reload,
0518:                                                    loadElement);
0519:                                        }
0520:
0521:                                        if (auto_reload) {
0522:                                            // register the modification time of the source file
0523:                                            long modification_time = getClassModificationTime(classname);
0524:                                            sModificationTimes
0525:                                                    .put(classname, new Long(
0526:                                                            modification_time));
0527:                                        }
0528:
0529:                                        // get an instance of the engine continuations config
0530:                                        if (null == mEngineContinuationConfigInstrument) {
0531:                                            Class config_class = loadClass("com.uwyn.rife.engine.EngineContinuationConfigInstrument");
0532:                                            try {
0533:                                                Constructor config_constructor = config_class
0534:                                                        .getConstructor(new Class[0]);
0535:                                                config_constructor
0536:                                                        .setAccessible(true);
0537:                                                mEngineContinuationConfigInstrument = config_constructor
0538:                                                        .newInstance(new Object[0]);
0539:                                            } catch (Exception e) {
0540:                                                throw new ClassNotFoundException(
0541:                                                        classname, e);
0542:                                            }
0543:                                        }
0544:
0545:                                        // get the continuation config instrument class
0546:                                        if (null == mContinuationConfigInstrumentClass) {
0547:                                            mContinuationConfigInstrumentClass = loadClass("com.uwyn.rife.continuations.ContinuationConfigInstrument");
0548:                                        }
0549:
0550:                                        // transform bytes on-the-fly into resumable bytes
0551:                                        byte[] resumable_bytes;
0552:                                        if (null == mResumerClass) {
0553:                                            mResumerClass = loadClass("com.uwyn.rife.continuations.instrument.ContinuationsBytecodeTransformer");
0554:                                        }
0555:                                        try {
0556:                                            if (null == mResumerMethod) {
0557:                                                mResumerMethod = mResumerClass
0558:                                                        .getDeclaredMethod(
0559:                                                                "transformIntoResumableBytes",
0560:                                                                new Class[] {
0561:                                                                        mContinuationConfigInstrumentClass,
0562:                                                                        byte[].class,
0563:                                                                        String.class });
0564:                                                mResumerMethod
0565:                                                        .setAccessible(true);
0566:                                            }
0567:                                            resumable_bytes = (byte[]) mResumerMethod
0568:                                                    .invoke(
0569:                                                            null,
0570:                                                            new Object[] {
0571:                                                                    mEngineContinuationConfigInstrument,
0572:                                                                    raw_bytes,
0573:                                                                    classname });
0574:                                        } catch (Exception e) {
0575:                                            throw new ClassNotFoundException(
0576:                                                    classname, e);
0577:                                        }
0578:
0579:                                        // define a package if needed
0580:                                        if (packagename != null) {
0581:                                            Package pkg = getPackage(packagename);
0582:                                            if (null == pkg) {
0583:                                                definePackage(packagename,
0584:                                                        null, null, null, null,
0585:                                                        null, null, null);
0586:                                            }
0587:                                        }
0588:
0589:                                        // intern the classname to get a synchronization lock monitor
0590:                                        // that is specific for the current class that is loaded and
0591:                                        // that will not lock up the classloading of all other classes
0592:                                        // by for instance synchronizing on this classloader
0593:                                        classname = classname.intern();
0594:                                        synchronized (classname) {
0595:                                            // make sure that the class has not been defined in the
0596:                                            // meantime, otherwise defining it again will trigger an
0597:                                            // exception;
0598:                                            // reuse the existing class if it has already been defined
0599:                                            c = findLoadedClass(classname);
0600:                                            if (null == c) {
0601:                                                // get the raw bytes of the class and define it for this classloader
0602:                                                if (null == resumable_bytes) {
0603:                                                    InstrumentationUtils
0604:                                                            .dumpClassBytes(
0605:                                                                    "adapted",
0606:                                                                    classname,
0607:                                                                    raw_bytes);
0608:                                                    c = defineClass(classname,
0609:                                                            raw_bytes, 0,
0610:                                                            raw_bytes.length);
0611:                                                } else {
0612:                                                    InstrumentationUtils
0613:                                                            .dumpClassBytes(
0614:                                                                    "adapted",
0615:                                                                    classname,
0616:                                                                    resumable_bytes);
0617:                                                    c = defineClass(
0618:                                                            classname,
0619:                                                            resumable_bytes,
0620:                                                            0,
0621:                                                            resumable_bytes.length);
0622:                                                }
0623:                                            }
0624:                                        }
0625:                                    }
0626:                                }
0627:                            }
0628:                        }
0629:                    }
0630:                }
0631:
0632:                // the ultimate fallback class loading
0633:                if (null == c && !mIsParentEngineclassloader) {
0634:                    try {
0635:                        c = getParent().loadClass(classname);
0636:                        //				if (c != null)
0637:                        //				{
0638:                        //					System.out.println("FALLBACK PARENT defined "+classname+" (ultimate falback)");
0639:                        //				}
0640:                    } catch (ClassNotFoundException e) {
0641:                        c = null;
0642:                    }
0643:                }
0644:                if (null == c) {
0645:                    try {
0646:                        c = findSystemClass(classname);
0647:                        //				System.out.println("FALLBACK SYSTEM defined "+classname);
0648:                    } catch (ClassNotFoundException e) {
0649:                        //				System.out.println("!!!!!! not found "+classname);
0650:                        throw e;
0651:                    }
0652:                }
0653:
0654:                // resolve the class if it's needed
0655:                if (resolve) {
0656:                    resolveClass(c);
0657:                }
0658:
0659:                assert c != null;
0660:
0661:                return c;
0662:            }
0663:
0664:            private void clearSiteCaches(String classname)
0665:                    throws ClassNotFoundException {
0666:                try {
0667:                    Class site_class = loadClass("com.uwyn.rife.engine.Site");
0668:                    Method repinstance_method = site_class.getDeclaredMethod(
0669:                            "getRepInstance", new Class[0]);
0670:                    Method clearcaches_method = site_class.getDeclaredMethod(
0671:                            "clearCaches", new Class[0]);
0672:                    Object site = repinstance_method
0673:                            .invoke(null, new Object[0]);
0674:                    if (site != null) {
0675:                        clearcaches_method.invoke(site, new Object[0]);
0676:                    }
0677:                } catch (Exception e) {
0678:                    e.printStackTrace();
0679:                    throw new ClassNotFoundException(classname, e);
0680:                }
0681:            }
0682:
0683:            private boolean isWebAppClass(String classname) {
0684:                try {
0685:                    String class_file = classname.replace('.', '/') + ".class";
0686:                    URL resource = getResource(class_file);
0687:                    if (resource != null) {
0688:                        //				System.out.println("resource_path : " + resource.toExternalForm());
0689:                        String resource_path = resource.getPath();
0690:                        String resource_protocol = resource.getProtocol();
0691:                        // if the resource lies in a WEB-INF dir, it's part
0692:                        // of a webapp
0693:                        if (resource_path.indexOf("WEB-INF") != -1) {
0694:                            return true;
0695:                        }
0696:                        // handle Orion's classloader resource protocol
0697:                        else if (resource_protocol != null
0698:                                && resource_protocol.equals("classloader")) {
0699:                            return true;
0700:                        }
0701:                        // if a specific rife webapp path collection has been
0702:                        // given, check against each entry
0703:                        else if (sRifeWebappPath != null) {
0704:                            if (resource_path.startsWith("jar:file:")) {
0705:                                resource_path = resource_path
0706:                                        .substring("jar:file:".length());
0707:                            }
0708:                            if (resource_path.startsWith("file:")) {
0709:                                resource_path = resource_path.substring("file:"
0710:                                        .length());
0711:                            }
0712:                            int exclamation_index = resource_path.indexOf("!");
0713:                            if (exclamation_index != -1) {
0714:                                resource_path = resource_path.substring(0,
0715:                                        exclamation_index);
0716:                            }
0717:                            resource_path = URLDecoder.decode(resource_path,
0718:                                    "ISO-8859-1");
0719:                            File resource_file = new File(resource_path);
0720:                            if (resource_file.exists()) {
0721:                                resource_path = resource_file
0722:                                        .getCanonicalPath();
0723:                                for (String path : sRifeWebappPath) {
0724:                                    if (resource_path.startsWith(path)) {
0725:                                        return true;
0726:                                    }
0727:                                }
0728:                            }
0729:                        }
0730:                    }
0731:                } catch (Throwable e) {
0732:                    return false;
0733:                }
0734:
0735:                return false;
0736:            }
0737:
0738:            private boolean hasRepClass() {
0739:                if (getParent() instanceof  EngineClassLoader) {
0740:                    return ((EngineClassLoader) getParent()).hasRepClass();
0741:                }
0742:
0743:                try {
0744:                    return findLoadedClass("com.uwyn.rife.rep.Rep") != null;
0745:                }
0746:                // fix to make it work with the IBM jvm
0747:                catch (ClassCircularityError e) {
0748:                    return true;
0749:                }
0750:            }
0751:
0752:            private boolean doAutoReload() {
0753:                Object value = System.getProperties()
0754:                        .get("ELEMENT_AUTO_RELOAD");
0755:
0756:                if (null == value) {
0757:                    return true;
0758:                }
0759:
0760:                if (value instanceof  String) {
0761:                    String string_value = (String) value;
0762:                    if (string_value.equals("1")
0763:                            || string_value.equalsIgnoreCase("t")
0764:                            || string_value.equalsIgnoreCase("true")
0765:                            || string_value.equalsIgnoreCase("y")
0766:                            || string_value.equalsIgnoreCase("yes")
0767:                            || string_value.equalsIgnoreCase("on")) {
0768:                        return true;
0769:                    }
0770:                }
0771:
0772:                return false;
0773:            }
0774:
0775:            public static String constructSourcePath(String classname) {
0776:                String source_location = null;
0777:                int innerclass_index = classname.indexOf("$");
0778:                if (innerclass_index != -1) {
0779:                    String containing_classname = classname.substring(0,
0780:                            innerclass_index);
0781:                    source_location = containing_classname.replace('.', '/')
0782:                            + ".java";
0783:                } else {
0784:                    source_location = classname.replace('.', '/') + ".java";
0785:                }
0786:
0787:                return source_location;
0788:            }
0789:
0790:            public byte[] getClassBytes(String className,
0791:                    boolean reloadAutomatically) throws ClassNotFoundException {
0792:                return getClassBytes(className, reloadAutomatically, false);
0793:            }
0794:
0795:            public byte[] getClassBytes(String className, boolean doAutoReload,
0796:                    boolean performCompilation) throws ClassNotFoundException {
0797:                byte[] raw_bytes = null;
0798:                String class_filename = className.replace('.', '/') + ".class";
0799:                URL class_resource = getResource(class_filename);
0800:                try {
0801:                    // if it couldn't be found or if it's outdated when auto-reload is
0802:                    // activated, compile the element
0803:                    if ((null == class_resource || (doAutoReload
0804:                            && performCompilation && isModified(className)))
0805:                            && (-1 == className.indexOf('$') || !className
0806:                                    .endsWith("BeanInfo"))) /// don't recompile for BeanInfo classes
0807:                    {
0808:                        try {
0809:                            if (!performCompilation && !hasRepClass()) {
0810:                                throw new ClassNotFoundException(className);
0811:                            } else {
0812:                                String source_location = constructSourcePath(className);
0813:                                File class_file = compileClass(className,
0814:                                        source_location);
0815:                                raw_bytes = FileUtils.readBytes(class_file);
0816:                            }
0817:                        } catch (Throwable e) {
0818:                            Class elementcompilation_failed_class = loadClass("com.uwyn.rife.engine.exceptions.ElementCompilationFailedException");
0819:                            if (e.getClass() == elementcompilation_failed_class) {
0820:                                throw (RuntimeException) e;
0821:                            }
0822:                            if (e instanceof  ClassNotFoundException) {
0823:                                throw (ClassNotFoundException) e;
0824:                            }
0825:
0826:                            throw new ClassNotFoundException(className, e);
0827:                        }
0828:                    }
0829:                    // otherwise just get the bytes of the classfile
0830:                    else {
0831:                        raw_bytes = mByteLoader.getClassBytes(class_filename,
0832:                                class_resource);
0833:                    }
0834:                } catch (ClassNotFoundException e) {
0835:                    throw e;
0836:                } catch (Throwable e) {
0837:                    if (e instanceof  RuntimeException) {
0838:                        throw (RuntimeException) e;
0839:                    }
0840:
0841:                    throw new ClassNotFoundException(
0842:                            "Error while reading the contents of the element class file '"
0843:                                    + className + "'.", e);
0844:                }
0845:
0846:                InstrumentationUtils.dumpClassBytes("initial", className,
0847:                        raw_bytes);
0848:
0849:                return raw_bytes;
0850:            }
0851:
0852:            File compileClass(String classname, String sourceLocation)
0853:                    throws ClassNotFoundException {
0854:                assert classname != null;
0855:                assert sourceLocation != null;
0856:                assert sourceLocation.endsWith(".java");
0857:
0858:                // try to find the script
0859:                URL source_resource = getSourceResource(sourceLocation, true);
0860:                if (null == source_resource) {
0861:                    throw new ClassNotFoundException(
0862:                            "Couldn't find the source file '" + sourceLocation
0863:                                    + "'.");
0864:                }
0865:
0866:                // get the package and the short classname of the element
0867:                int classname_index = classname.lastIndexOf(".");
0868:                String element_package = null;
0869:                String element_classname = null;
0870:                if (classname_index != -1) {
0871:                    element_package = classname.substring(0, classname_index);
0872:                    element_classname = classname
0873:                            .substring(classname_index + 1);
0874:                } else {
0875:                    element_classname = classname;
0876:                }
0877:
0878:                // setup everything to perform the conversion of the element to java sources
0879:                // and to compile it into a java class
0880:                Object generation_path_object = null;
0881:                try {
0882:                    Class tests_class = loadClass("com.uwyn.rife.config.RifeConfig$Engine");
0883:                    Method method = tests_class.getMethod(
0884:                            "getElementGenerationPath", (Class[]) null);
0885:                    generation_path_object = method.invoke(null,
0886:                            (Object[]) null);
0887:                } catch (Throwable e) {
0888:                    throw new ClassNotFoundException(
0889:                            "Couldn't obtain the element bytecode generation path.",
0890:                            e);
0891:                }
0892:
0893:                String generation_path = ((String) generation_path_object)
0894:                        + File.separatorChar;
0895:                String package_dir = "";
0896:                if (element_package != null) {
0897:                    package_dir = generation_path
0898:                            + element_package.replace('.', File.separatorChar)
0899:                            + File.separator;
0900:                } else {
0901:                    package_dir = generation_path;
0902:                }
0903:                String filename_java = null;
0904:                try {
0905:                    filename_java = URLDecoder.decode(
0906:                            source_resource.getPath(), "ISO-8859-1");
0907:                } catch (UnsupportedEncodingException e) {
0908:                    throw new ClassNotFoundException(
0909:                            "Couldn't decode the resource path '"
0910:                                    + source_resource.getPath() + "'.", e);
0911:                }
0912:                String filename_class = package_dir + element_classname
0913:                        + ".class";
0914:                File file_packagedir = new File(package_dir);
0915:                File file_class = new File(filename_class);
0916:
0917:                // prepare the package directory
0918:                if (!file_packagedir.exists()) {
0919:                    if (!file_packagedir.mkdirs()) {
0920:                        throw new ClassNotFoundException(
0921:                                "Couldn't create the package directory : '"
0922:                                        + package_dir + "'.");
0923:                    }
0924:                } else if (!file_packagedir.isDirectory()) {
0925:                    throw new ClassNotFoundException("The package directory '"
0926:                            + package_dir + "' exists but is not a directory.");
0927:                } else if (!file_packagedir.canWrite()) {
0928:                    throw new ClassNotFoundException("The package directory '"
0929:                            + package_dir + "' is not writable.");
0930:                }
0931:
0932:                // check if the class wasn't already compiled due to other classes
0933:                // in the same source file
0934:                boolean is_already_compiled = false;
0935:                long source_modification_time = -1L;
0936:                if (file_class.exists()) {
0937:                    long class_modification_time = file_class.lastModified();
0938:                    source_modification_time = getSourceModificationTime(source_resource);
0939:                    if (class_modification_time >= source_modification_time) {
0940:                        is_already_compiled = true;
0941:                    }
0942:                }
0943:
0944:                if (!is_already_compiled) {
0945:                    try {
0946:                        Class classloader_classpath_class = loadClass("com.uwyn.rife.engine.EngineClassLoaderClasspath");
0947:                        Field classloader_classpath_field = classloader_classpath_class
0948:                                .getField("CLASSPATH");
0949:                        String classloader_classpath = (String) classloader_classpath_field
0950:                                .get(null);
0951:
0952:                        Class tests_class = loadClass("com.uwyn.rife.tools.CompilationUtils");
0953:                        Method method = tests_class.getMethod("compile",
0954:                                new Class[] { String.class, File.class,
0955:                                        String.class, String.class });
0956:                        generation_path_object = method
0957:                                .invoke(null, new Object[] { filename_java,
0958:                                        file_class, generation_path,
0959:                                        classloader_classpath });
0960:                    } catch (InvocationTargetException e) {
0961:                        Class compilation_failed_class = loadClass("com.uwyn.rife.tools.exceptions.CompilationFailedException");
0962:
0963:                        Throwable target_exception = e.getTargetException();
0964:                        if (compilation_failed_class == target_exception
0965:                                .getClass()) {
0966:                            String sourcefilename = null;
0967:                            String errors = null;
0968:                            Throwable cause = null;
0969:
0970:                            try {
0971:                                Method sourcefilename_method = compilation_failed_class
0972:                                        .getMethod("getSourceFilename",
0973:                                                (Class[]) null);
0974:                                sourcefilename = (String) sourcefilename_method
0975:                                        .invoke(target_exception,
0976:                                                (Object[]) null);
0977:                                Method errors_method = compilation_failed_class
0978:                                        .getMethod("getErrors", (Class[]) null);
0979:                                errors = (String) errors_method.invoke(
0980:                                        target_exception, (Object[]) null);
0981:                                Method cause_method = compilation_failed_class
0982:                                        .getMethod("getCause", (Class[]) null);
0983:                                cause = (Throwable) cause_method.invoke(
0984:                                        target_exception, (Object[]) null);
0985:                            } catch (Throwable e2) {
0986:                                throw new ClassNotFoundException(
0987:                                        "Unexpected error while compiling the element source '"
0988:                                                + filename_java + "'+.", e);
0989:                            }
0990:
0991:                            Object elementcompilation_failed_instance = null;
0992:
0993:                            try {
0994:                                Class elementcompilation_failed_class = loadClass("com.uwyn.rife.engine.exceptions.ElementCompilationFailedException");
0995:                                Constructor elementcompilation_failed_constructor = elementcompilation_failed_class
0996:                                        .getConstructor(new Class[] {
0997:                                                String.class, String.class,
0998:                                                Throwable.class });
0999:                                elementcompilation_failed_instance = elementcompilation_failed_constructor
1000:                                        .newInstance(new Object[] {
1001:                                                sourcefilename, errors, cause });
1002:                            } catch (Throwable e2) {
1003:                                throw new ClassNotFoundException(
1004:                                        "Unexpected error while compiling the element source '"
1005:                                                + filename_java + "'+.", e);
1006:                            }
1007:
1008:                            throw (RuntimeException) elementcompilation_failed_instance;
1009:                        } else {
1010:                            throw new ClassNotFoundException(
1011:                                    "Unexpected error while compiling the element source '"
1012:                                            + filename_java + "'.", e);
1013:                        }
1014:                    } catch (Throwable e) {
1015:                        throw new ClassNotFoundException(
1016:                                "Unexpected error while compiling the element source '"
1017:                                        + filename_java + "'.", e);
1018:                    }
1019:                }
1020:
1021:                assert file_class != null;
1022:                assert file_class.exists();
1023:                assert file_class.canRead();
1024:
1025:                return file_class;
1026:            }
1027:
1028:            private URL getSourceResource(String sourceLocation,
1029:                    boolean getElement) {
1030:                URL source_resource = getResource(sourceLocation);
1031:                if (null == source_resource && getElement) {
1032:                    source_resource = getResource(DEFAULT_IMPLEMENTATIONS_PATH
1033:                            + sourceLocation);
1034:                }
1035:                return source_resource;
1036:            }
1037:
1038:            private boolean isElement(String internedClassname, byte[] bytes,
1039:                    boolean doAutoReload) throws ClassNotFoundException {
1040:                return mElementDetector.detect(internedClassname, bytes,
1041:                        doAutoReload);
1042:            }
1043:
1044:            private boolean isConstrained(String internedClassname, byte[] bytes)
1045:                    throws ClassBytesNotFoundException {
1046:                return mConstrainedDetector.isConstrained(internedClassname,
1047:                        bytes);
1048:            }
1049:
1050:            private long getClassModificationTime(String classname) {
1051:                return getSourceModificationTime(getSourceResource(
1052:                        constructSourcePath(classname), true));
1053:            }
1054:
1055:            public static long getSourceModificationTime(URL sourceResource) {
1056:                if (null == sourceResource) {
1057:                    return -1;
1058:                }
1059:
1060:                try {
1061:                    return ModificationTimeClasspath
1062:                            .getModificationTime(sourceResource);
1063:                } catch (Throwable e) {
1064:                    return -1;
1065:                }
1066:            }
1067:
1068:            private boolean isModified(String classname) {
1069:                Long last_modification_time = sModificationTimes.get(classname);
1070:                if (null == last_modification_time) {
1071:                    return false;
1072:                }
1073:
1074:                long current_modification_time = getClassModificationTime(classname);
1075:                if (current_modification_time <= last_modification_time
1076:                        .longValue()) {
1077:                    return false;
1078:                }
1079:
1080:                return true;
1081:            }
1082:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.