33import act .Act ;
44import act .asm .ClassReader ;
55import act .asm .ClassWriter ;
6+ import act .boot .BootstrapClassLoader ;
67import act .controller .meta .ControllerClassMetaInfo ;
78import act .controller .meta .ControllerClassMetaInfoHolder ;
89import act .controller .meta .ControllerClassMetaInfoManager ;
9- import act .util .ByteCodeVisitor ;
10- import act .util .ClassNames ;
11- import act .util .Files ;
12- import act .util .Jars ;
10+ import act .job .meta .JobClassMetaInfo ;
11+ import act .job .meta .JobClassMetaInfoManager ;
12+ import act .util .*;
1313import org .osgl ._ ;
1414import org .osgl .exception .NotAppliedException ;
1515import org .osgl .logging .L ;
3131/**
3232 * The top level class loader to load a specific application classes into JVM
3333 */
34- public class AppClassLoader extends ClassLoader implements ControllerClassMetaInfoHolder , AppService <AppClassLoader > {
34+ public class AppClassLoader extends ClassLoader implements ControllerClassMetaInfoHolder , AppService <AppClassLoader >, ActClassLoader {
3535 protected final static Logger logger = L .get (AppClassLoader .class );
3636 private App app ;
3737 private Map <String , byte []> libClsCache = C .newMap ();
3838 private boolean destroyed ;
3939 protected ControllerClassMetaInfoManager controllerInfo = new ControllerClassMetaInfoManager ();
40+ protected JobClassMetaInfoManager jobInfo = new JobClassMetaInfoManager ();
4041
4142 public AppClassLoader (App app ) {
4243 super (Act .class .getClassLoader ());
@@ -62,6 +63,7 @@ public final App app() {
6263 public final void destroy () {
6364 libClsCache .clear ();
6465 controllerInfo .destroy ();
66+ jobInfo .destroy ();
6567 releaseResources ();
6668 destroyed = true ;
6769 }
@@ -77,14 +79,33 @@ public ControllerClassMetaInfo controllerClassMetaInfo(String controllerClassNam
7779 return controllerInfo .controllerMetaInfo (controllerClassName );
7880 }
7981
80- public ControllerClassMetaInfoManager controllerClassMetaInfoManager2 () {
82+ public ControllerClassMetaInfoManager controllerClassMetaInfoManager () {
8183 return controllerInfo ;
8284 }
8385
86+ public JobClassMetaInfo jobClassMetaInfo (String jobClassName ) {
87+ return jobInfo .jobMetaInfo (jobClassName );
88+ }
89+
90+ public JobClassMetaInfoManager jobClassMetaInfoManager () {
91+ return jobInfo ;
92+ }
93+
8494 public boolean isSourceClass (String className ) {
8595 return false ;
8696 }
8797
98+ public Class <?> loadedClass (String name ) {
99+ Class <?> c = findLoadedClass (name );
100+ if (null == c ) {
101+ ClassLoader p = getParent ();
102+ if (null != p && (p instanceof ActClassLoader || p instanceof BootstrapClassLoader )) {
103+ return ((ActClassLoader )p ).loadedClass (name );
104+ }
105+ }
106+ return c ;
107+ }
108+
88109 @ Override
89110 protected Class <?> loadClass (String name , boolean resolve ) throws ClassNotFoundException {
90111 Class <?> c = findLoadedClass (name );
@@ -138,19 +159,22 @@ protected void scanByteCode(Iterable<String> classes, _.Function<String, byte[]>
138159 cr .accept (theVisitor , 0 );
139160 for (AppByteCodeScanner scanner : scanners ) {
140161 scanner .scanFinished (className );
141- Set <String > ss = scanner .dependencyClasses ();
162+ Map < Class <? extends AppByteCodeScanner >, Set <String > > ss = scanner .dependencyClasses ();
142163 if (ss .isEmpty ()) {
143164 logger .debug ("no dependencies found for %s by scanner %s" , className , scanner );
144165 continue ;
145166 }
146- for (String dependencyClass : ss ) {
147- logger .debug ("dependencies[%s] found for %s by scanner %s" , dependencyClass , className , scanner );
148- List <AppByteCodeScanner > l = dependencies .get (dependencyClass );
149- if (null == l ) {
150- l = C .newList ();
151- dependencies .put (dependencyClass , l );
167+ for (Class <? extends AppByteCodeScanner > scannerClass : ss .keySet ()) {
168+ AppByteCodeScanner scannerA = scannerManager .byteCodeScannerByClass (scannerClass );
169+ for (String dependencyClass : ss .get (scannerClass )) {
170+ logger .debug ("dependencies[%s] found for %s by scanner %s" , dependencyClass , className , scannerA );
171+ List <AppByteCodeScanner > l = dependencies .get (dependencyClass );
172+ if (null == l ) {
173+ l = C .newList ();
174+ dependencies .put (dependencyClass , l );
175+ }
176+ if (!l .contains (scanner )) l .add (scannerA );
152177 }
153- if (!l .contains (scanner )) l .add (scanner );
154178 }
155179 }
156180 }
@@ -164,21 +188,26 @@ protected void scanByteCode(Iterable<String> classes, _.Function<String, byte[]>
164188 visitors .add (scanner .byteCodeVisitor ());
165189 }
166190 ByteCodeVisitor theVisitor = ByteCodeVisitor .chain (visitors );
167- ClassReader cr = new ClassReader (libClsCache . get (className ));
191+ ClassReader cr = new ClassReader (bytecodeProvider . apply (className ));
168192 cr .accept (theVisitor , 0 );
169193 for (AppByteCodeScanner scanner : scanners ) {
170194 scanner .scanFinished (className );
171- Set <String > ss = scanner .dependencyClasses ();
195+ Map < Class <? extends AppByteCodeScanner >, Set <String > > ss = scanner .dependencyClasses ();
172196 if (ss .isEmpty ()) {
197+ logger .debug ("no dependencies found for %s by scanner %s" , className , scanner );
173198 continue ;
174199 }
175- for (String dependencyClass : ss ) {
176- List <AppByteCodeScanner > l = dependencies .get (dependencyClass );
177- if (null == l ) {
178- l = C .newList ();
179- dependencies .put (dependencyClass , l );
200+ for (Class <? extends AppByteCodeScanner > scannerClass : ss .keySet ()) {
201+ AppByteCodeScanner scannerA = scannerManager .byteCodeScannerByClass (scannerClass );
202+ for (String dependencyClass : ss .get (scannerClass )) {
203+ logger .debug ("dependencies[%s] found for %s by scanner %s" , dependencyClass , className , scannerA );
204+ List <AppByteCodeScanner > l = dependencies .get (dependencyClass );
205+ if (null == l ) {
206+ l = C .newList ();
207+ dependencies .put (dependencyClass , l );
208+ }
209+ if (!l .contains (scanner )) l .add (scannerA );
180210 }
181- if (!l .contains (scanner )) l .add (scanner );
182211 }
183212 }
184213 }
@@ -208,9 +237,24 @@ protected void preloadClassFile(File base, File file) {
208237 libClsCache .put (ClassNames .sourceFileNameToClassName (base , file .getAbsolutePath ().replace (".class" , ".java" )), bytes );
209238 }
210239
240+ protected byte [] loadAppClassFromDisk (String name ) {
241+ File base = new File (app ().layout ().target (app ().base ()), "classes" );
242+ if (base .canRead () && base .isDirectory ()) {
243+ String path = ClassNames .classNameToClassFileName (name );
244+ File classFile = new File (base , path );
245+ if (classFile .canRead ()) {
246+ return IO .readContent (classFile );
247+ }
248+ }
249+ return null ;
250+ }
251+
211252 private Class <?> loadAppClass (String name , boolean resolve ) {
212253 byte [] bytecode = appBytecode (name );
213- if (null == bytecode ) return null ;
254+ if (null == bytecode ) {
255+ bytecode = loadAppClassFromDisk (name );
256+ if (null == bytecode ) return null ;
257+ }
214258 if (!app ().config ().needEnhancement (name )) {
215259 Class <?> c = super .defineClass (name , bytecode , 0 , bytecode .length , DOMAIN );
216260 if (resolve ) {
@@ -239,6 +283,7 @@ protected byte[] enhance(String className, byte[] bytecode) {
239283 }
240284
241285 private byte [] asmEnhance (String className , byte [] bytecode ) {
286+ if (!enhanceEligible (className )) return bytecode ;
242287 _ .Var <ClassWriter > cw = _ .var (null );
243288 ByteCodeVisitor enhancer = Act .enhancerManager ().appEnhancer (app , className , cw );
244289 if (null == enhancer ) {
@@ -312,4 +357,9 @@ public boolean test(String s) {
312357 };
313358 static _ .Predicate <String > SAFE_CLASS = S .F .endsWith (".class" ).and (SYS_CLASS_NAME .negate ());
314359 }
360+
361+ protected static boolean enhanceEligible (String name ) {
362+ boolean sys = name .startsWith ("java" ) || name .startsWith ("com.google" ) || name .startsWith ("org.apache" ) || name .startsWith ("org.springframework" );
363+ return !sys ;
364+ }
315365}
0 commit comments