210 " |
210 " |
211 ! ! |
211 ! ! |
212 |
212 |
213 !JavaClassReader class methodsFor:'file reading'! |
213 !JavaClassReader class methodsFor:'file reading'! |
214 |
214 |
215 loadClass:aClassName |
215 readClass: aClassName |
216 "reads a class, installs and returns it. |
216 "reads a class, and returns it. |
217 The classes string constants are resolved & <clinit> is called, |
217 <clinit> is called, class is not installed" |
218 if it implements it." |
218 |
219 |
219 ^ self readClass: aClassName ignoring: Set new. |
220 ^self loadClassLazy: aClassName |
|
221 |
|
222 |
|
223 " |
|
224 JavaClassReader loadClass:'awt/Component' |
|
225 JavaClassReader loadClass:'awt/Button' |
|
226 JavaClassReader loadClass:'browser/AddButton' |
|
227 |
|
228 JavaClassReader loadClass:'java/lang/Object' |
|
229 JavaClassReader loadClass:'java/lang/AbstractMethodError' |
|
230 JavaClassReader loadClass:'java/lang/Thread' |
|
231 " |
|
232 |
220 |
233 "Created: / 15-04-1996 / 14:58:53 / cg" |
221 "Created: / 15-04-1996 / 14:58:53 / cg" |
234 "Modified: / 20-10-1998 / 17:24:54 / cg" |
222 "Modified: / 20-10-1998 / 17:24:54 / cg" |
235 "Modified: / 08-09-2011 / 08:10:58 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
223 "Modified: / 08-09-2011 / 08:10:58 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
236 ! |
224 ! |
237 |
225 |
238 loadClassLazy: internalJavaClassName |
226 readClass: className ignoring: classesBeingLoadedOrNil |
239 ^ self loadClassLazy: internalJavaClassName ignoring: Set new. |
227 "reads a class, and returns it. |
240 |
228 <clinit> is called, class is not installed |
241 "Created: / 08-04-2011 / 18:00:28 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
242 "Modified: / 11-04-2011 / 19:31:04 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
243 ! |
|
244 |
|
245 loadClassLazy: className classpath: classpath |
|
246 |
|
247 ^self loadClassLazy: className classpath: classpath ignoring: Set new. |
|
248 |
|
249 "Created: / 08-09-2011 / 08:05:39 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
250 ! |
|
251 |
|
252 loadClassLazy: className classpath: classpath ignoring: classesBeingLoaded |
|
253 "private helper: |
|
254 reads a class, installs and returns it. |
|
255 The class is searched along the ClassPath. |
|
256 |
229 |
257 className expected format: |
230 className expected format: |
258 foo.bar.Baz - normal class |
231 foo.bar.Baz - normal class |
259 foo/bar/Baz - alternative format |
232 foo/bar/Baz - alternative format |
260 [[Lfoo/bar/Baz; - array |
233 [[Lfoo/bar/Baz; - array |
261 [[I - primitive array |
234 [[I - primitive array" |
262 |
235 |
263 This is a partial load (to load other classes): |
236 | rslt clsName cls classesBeingLoaded | |
264 - The classes stringConstants are not fixed to be JavaStrings |
237 |
265 (i.e they are still ST-Strings). |
|
266 - The class is NOT initialized." |
|
267 |
|
268 | rslt clsName cls loadedClass | |
|
269 (JavaDescriptor isJavaPrimitiveArrayName: className) ifTrue: [ |
238 (JavaDescriptor isJavaPrimitiveArrayName: className) ifTrue: [ |
270 ^ (JavaDescriptor fromString: className) javaClass. |
239 ^ (JavaDescriptor fromString: className) javaClass. |
271 ]. |
240 ]. |
|
241 (cls := Java javaRegistry at: clsName) ifNotNil: [ ^ cls. ]. |
272 clsName := self getCleanClassNameFrom: className. |
242 clsName := self getCleanClassNameFrom: className. |
273 (classesBeingLoaded notNil and: [ classesBeingLoaded includes: clsName ]) ifTrue: [ |
243 (classesBeingLoadedOrNil notNil |
274 ('oops - recursive load of ' , clsName , ' attempted') printNL. |
244 and: [ classesBeingLoadedOrNil includes: clsName ]) |
275 self halt: 'should not happen'. |
245 ifTrue: [ self halt: 'recursive load - should not happen'. ]. |
276 ^ JavaUnresolvedClassConstant fullName: clsName |
246 classesBeingLoadedOrNil isNil ifTrue: [ |
277 ]. |
247 classesBeingLoaded := Set with: clsName |
278 (cls := Java at: clsName) notNil ifTrue: [ |
248 ] ifFalse: [ |
279 ('oops - ' , clsName , ' is already loaded') printNL. |
249 classesBeingLoaded := classesBeingLoadedOrNil |
280 ^ cls |
250 add: clsName; |
281 ]. |
251 yourself. |
282 classesBeingLoaded isNil ifTrue: [ loadedClass := Set with: clsName ] ifFalse: [ |
252 ]. |
283 loadedClass := Set withAll: classesBeingLoaded. |
253 Java effectiveClassPath do: [ |
284 loadedClass add: clsName. |
|
285 ]. |
|
286 classpath do: [ |
|
287 :path | |
254 :path | |
288 | nm p zar entry zipFile read | |
255 | nm p zar entry zipFile read | |
289 |
256 |
290 Verbose == true ifTrue: [ |
|
291 Transcript showCR: 'trying ' , path asFilename pathName , ' ...'. |
|
292 ]. |
|
293 p := path. |
257 p := path. |
294 p asFilename isDirectory ifTrue: [ |
258 p asFilename isDirectory ifTrue: [ |
295 self halt. |
|
296 (p endsWith: Filename separator) ifFalse: [ |
259 (p endsWith: Filename separator) ifFalse: [ |
297 p := p , (Filename separator asString) |
260 p := p , (Filename separator asString) |
298 ]. |
261 ]. |
299 (Array |
262 (Array |
300 with: clsName |
263 with: clsName |
301 with: clsName asLowercase |
264 with: clsName asLowercase |
302 with: clsName asUppercase) |
265 with: clsName asUppercase) |
303 do: [ |
266 do: [ |
304 :tryName | |
267 :tryName | |
305 nm := p , tryName , '.class'. |
268 nm := p , tryName , '.class'. |
306 Verbose == true ifTrue: [ Transcript showCR: 'trying ' , nm , ' ...'. ]. |
|
307 nm asFilename exists ifTrue: [ |
269 nm asFilename exists ifTrue: [ |
308 (Java isExcludedFromClassPath: nm) ifFalse: [ |
270 (Java isExcludedFromClassPath: nm) ifFalse: [ |
309 self halt. rslt := self loadFileLazy: nm ignoring: loadedClass. |
271 self breakPoint:#mh. |
310 rslt notNil ifTrue: [ ^ rslt ]. |
272 "means we are successfully going to read something :)" |
|
273 rslt := self readFile: nm ignoring: classesBeingLoaded. |
|
274 rslt notNil ifTrue: [ |
|
275 ^ rslt. |
|
276 ]. |
311 ] |
277 ] |
312 ]. |
278 ]. |
313 ] |
279 ] |
314 ] ifFalse: [ |
280 ] ifFalse: [ |
315 Verbose == true ifTrue: [ |
|
316 Transcript |
|
317 showCR: 'trying ' , (p asFilename withSuffix: 'jar') pathName , ' ...'. |
|
318 Transcript |
|
319 showCR: 'and ' , (p asFilename withSuffix: 'zip') pathName , ' ...'. |
|
320 ]. |
|
321 ((zipFile := p asFilename withSuffix: 'jar') exists |
281 ((zipFile := p asFilename withSuffix: 'jar') exists |
322 or: [ (zipFile := p asFilename withSuffix: 'zip') exists ]) |
282 or: [ (zipFile := p asFilename withSuffix: 'zip') exists ]) |
323 ifTrue: [ |
283 ifTrue: [ |
324 zar := JavaArchiveCache at: zipFile |
284 zar := JavaArchiveCache at: zipFile |
325 ifAbsentPut: [ ZipArchive oldFileNamed: zipFile ]. |
285 ifAbsentPut: [ ZipArchive oldFileNamed: zipFile ]. |
326 read := [ |
286 read := [ |
327 nm := clsName , '.class'. |
287 nm := clsName , '.class'. |
328 entry := zar extract: nm. |
288 entry := zar extract: nm. |
329 entry notNil ifTrue: [ |
289 entry notNil ifTrue: [ |
330 (Java isExcludedFromClassPath: nm) ifFalse: [ |
290 (Java isExcludedFromClassPath: nm) ifFalse: [ |
331 rslt := self loadStreamLazy: (entry readStream) ignoring: loadedClass. |
291 rslt := self readStream: (entry readStream) ignoring: classesBeingLoaded. |
332 rslt notNil ifTrue: [ ^ rslt ]. |
292 rslt notNil ifTrue: [ ^ rslt ]. |
333 ] |
293 ] |
334 ] |
294 ] |
335 ]. |
295 ]. |
336 JavaClassReader invalidClassFormatSignal |
296 JavaClassReader invalidClassFormatSignal |
341 ] |
301 ] |
342 do: [ read value ]. |
302 do: [ read value ]. |
343 ] |
303 ] |
344 ] |
304 ] |
345 ]. |
305 ]. |
346 ^ nil. |
306 |
347 |
307 |
348 "Modified: / 14-08-1997 / 11:38:42 / stefan" |
308 "Created: / 15-04-1996 / 14:58:53 / cg" |
349 "Modified: / 17-09-1998 / 20:51:25 / cg" |
309 "Modified: / 20-10-1998 / 17:24:54 / cg" |
350 "Modified: / 21-03-2011 / 12:42:12 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
310 "Modified: / 08-09-2011 / 08:10:58 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
351 "Created: / 12-08-2011 / 08:48:34 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
311 ! |
352 ! |
312 |
353 |
313 readFile: aFilename ignoring: classesBeingLoaded |
354 loadClassLazy: aClassName ignoring: classesBeingLoaded |
|
355 | class loader classObject | |
|
356 |
|
357 "Try supplied class loader, if any" |
|
358 loader := ClassLoaderQuerySignal query. |
|
359 (JavaDescriptor isJavaPrimitiveArrayName: aClassName) ifTrue: [ |
|
360 ^ (JavaDescriptor fromString: aClassName) javaClass. |
|
361 ]. |
|
362 loader |
|
363 ifNil: [ |
|
364 "Try primordial (bootstrap) class loader, if it finds a class, return it" |
|
365 class := self |
|
366 loadClassLazy: aClassName |
|
367 classpath: Java release classPath |
|
368 ignoring: classesBeingLoaded. |
|
369 class notNil ifTrue: [ |
|
370 JavaClassReader postLoadActions. |
|
371 ((aClassName |
|
372 indexOfSubCollection: '[L' |
|
373 startingAt: 1 |
|
374 ifAbsent: [ -1 ] |
|
375 caseSensitive: true) ~= -1) ifTrue: [ |
|
376 ^ JavaClassReader makeArrayOf: class |
|
377 withDimensions: (aClassName occurrencesOf: $[) |
|
378 ]. |
|
379 ^ class. |
|
380 ]. |
|
381 "No classloader specified, try system class loader" |
|
382 loader := (Java classForName: 'java.lang.ClassLoader') instVarNamed: #scl. |
|
383 loader isNil ifTrue: [ |
|
384 loader := (Java classForName: 'java.lang.ClassLoader') |
|
385 perform: #'getSystemClassLoader()Ljava/lang/ClassLoader;'. |
|
386 loader isNil ifTrue: [ |
|
387 self error: 'Cannot obtain system class loader!!'. |
|
388 ^ self. |
|
389 ]. |
|
390 ]. |
|
391 ]. |
|
392 classObject := loader |
|
393 perform: #'loadClass(Ljava/lang/String;)Ljava/lang/Class;' |
|
394 with: (Java as_String: (aClassName copyReplaceAll: $/ with: $.)). |
|
395 classObject notNil ifTrue: [ ^ JavaVM classForJavaClassObject: classObject. ]. |
|
396 "Bad, class not found..." |
|
397 JavaVM throwClassNotFoundException: aClassName. |
|
398 |
|
399 "Modified: / 14-08-1997 / 11:38:42 / stefan" |
|
400 "Modified: / 17-09-1998 / 20:51:25 / cg" |
|
401 "Modified: / 21-03-2011 / 12:42:12 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
402 "Modified: / 08-09-2011 / 08:25:48 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
403 ! |
|
404 |
|
405 loadClassesIn: directory |
|
406 "load all classes (.class files, strictly speaking) found in given directory. |
|
407 The argument is string containing the name of the directory. |
|
408 |
|
409 Returns a set of loaded classes." |
|
410 |
|
411 ^self loadClassesIn: directory matching: '*' |
|
412 |
|
413 "Modified: / 11-06-2011 / 13:35:08 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
414 ! |
|
415 |
|
416 loadClassesIn: directory matching: pattern |
|
417 "load all classes (.class files, strictly speaking) found in given directory. |
|
418 The arguments are a string containing the name of the directory |
|
419 and a class name pattern. Only classes matching the pattern are loaded. |
|
420 class names are matched using String>>matches:. |
|
421 |
|
422 Returns a set of loaded classes." |
|
423 |
|
424 | dir dirString className loadedClasses | |
|
425 |
|
426 dir := directory asFilename asAbsoluteFilename. |
|
427 loadedClasses := Set new. |
|
428 Java addToClassPath: dir pathName. |
|
429 dir recursiveDirectoryContentsAsFilenamesDo: |
|
430 [:filename | |
|
431 (filename isRegularFile and: [ filename suffix = #class ]) |
|
432 ifTrue: |
|
433 [ dirString := dir pathName. |
|
434 className := filename withoutSuffix pathName. |
|
435 className := className subString: dirString size + 2 to: className size. |
|
436 className := className copyReplaceAll: (Filename separator) with: $.. |
|
437 (className matches: pattern) ifTrue: |
|
438 [loadedClasses add: (self loadClass: className)]]]. |
|
439 |
|
440 ^ loadedClasses. |
|
441 |
|
442 "Modified: / 29-04-2011 / 17:43:32 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
443 "Created: / 11-06-2011 / 13:34:39 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
444 "Modified: / 11-06-2011 / 16:19:40 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
445 ! |
|
446 |
|
447 loadFile:aFilename |
|
448 "reads a class from aFilename, installs and returns it. |
|
449 The classes strings are fixed and its class-init function is called." |
|
450 |
|
451 self loadFileLazy:aFilename ignoring:(Set new). |
|
452 |
|
453 "Modified: / 08-09-2011 / 08:01:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
454 ! |
|
455 |
|
456 loadFileLazy:aFilename ignoring:classesBeingLoaded |
|
457 "reads a class from aFilename, installs and returns it. |
|
458 Strings are fixed and classrefs are fixed, |
|
459 but NO no class-init functions are called." |
|
460 |
|
461 |aClass pool| |
|
462 |
|
463 aClass := self readFile:aFilename ignoring:classesBeingLoaded. |
|
464 aClass notNil ifTrue:[ |
|
465 aClass isJavaClass ifTrue:[ |
|
466 "/ a java class |
|
467 Java at:(aClass fullName asSymbol) put:aClass. |
|
468 |
|
469 classesBeingLoaded remove:aClass fullName ifAbsent:nil. |
|
470 |
|
471 JavaUnresolvedConstant resolveFor:aClass. |
|
472 ] ifFalse:[ |
|
473 "/ a smalltalk class |
|
474 "/ self halt. |
|
475 aClass inspect. |
|
476 ] |
|
477 ]. |
|
478 ^ aClass |
|
479 |
|
480 " |
|
481 JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class' |
|
482 |
|
483 '/phys/ibm3/java/lib/java/lang' asFilename |
|
484 directoryContents do:[:nm | |
|
485 (nm endsWith:'.class') ifTrue:[ |
|
486 ('/phys/ibm3/java/lib/java/lang/' , nm) printNL. |
|
487 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/' , nm |
|
488 ] |
|
489 ]. |
|
490 |
|
491 '/phys/ibm3/java/lib/java/io' asFilename |
|
492 directoryContents do:[:nm | |
|
493 (nm endsWith:'.class') ifTrue:[ |
|
494 ('/phys/ibm3/java/lib/java/io/' , nm) printNL. |
|
495 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/io/' , nm |
|
496 ] |
|
497 ]. |
|
498 |
|
499 '/phys/ibm3/java/lib/java/net' asFilename |
|
500 directoryContents do:[:nm | |
|
501 (nm endsWith:'.class') ifTrue:[ |
|
502 ('/phys/ibm3/java/lib/java/net/' , nm) printNL. |
|
503 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/net/' , nm |
|
504 ] |
|
505 ]. |
|
506 |
|
507 '/phys/ibm3/java/lib/java/util' asFilename |
|
508 directoryContents do:[:nm | |
|
509 (nm endsWith:'.class') ifTrue:[ |
|
510 ('/phys/ibm3/java/lib/java/util/' , nm) printNL. |
|
511 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/util/' , nm |
|
512 ] |
|
513 ]. |
|
514 |
|
515 '/phys/ibm3/java/lib/java/awt' asFilename |
|
516 directoryContents do:[:nm | |
|
517 (nm endsWith:'.class') ifTrue:[ |
|
518 ('/phys/ibm3/java/lib/java/awt/' , nm) printNL. |
|
519 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/awt/' , nm |
|
520 ] |
|
521 ]. |
|
522 |
|
523 '/phys/ibm3/java/lib/java/applet' asFilename |
|
524 directoryContents do:[:nm | |
|
525 (nm endsWith:'.class') ifTrue:[ |
|
526 ('/phys/ibm3/java/lib/java/applet/' , nm) printNL. |
|
527 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/applet/' , nm |
|
528 ] |
|
529 ]. |
|
530 |
|
531 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/AbstractMethodError.class' |
|
532 JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/Thread.class' |
|
533 " |
|
534 |
|
535 "Created: / 15.4.1996 / 14:58:53 / cg" |
|
536 "Modified: / 12.5.1998 / 22:06:52 / cg" |
|
537 ! |
|
538 |
|
539 loadStreamLazy:aStream ignoring:classesBeingLoaded |
|
540 "reads a class from aStream, installs and returns it. |
|
541 Strings are fixed and classrefs are fixed, |
|
542 but NO no class-init functions are called." |
|
543 |
|
544 |javaClass pool| |
|
545 |
|
546 javaClass := self readStream:aStream ignoring:classesBeingLoaded. |
|
547 javaClass notNil ifTrue:[ |
|
548 Java at:(javaClass fullName asSymbol) put:javaClass. |
|
549 |
|
550 classesBeingLoaded remove:javaClass fullName ifAbsent:nil. |
|
551 |
|
552 JavaUnresolvedConstant resolveFor:javaClass. |
|
553 ]. |
|
554 ^ javaClass |
|
555 |
|
556 "Created: / 30.3.1998 / 17:59:02 / cg" |
|
557 ! |
|
558 |
|
559 postLoadActions |
|
560 "Resolve all classes' string constants. |
|
561 Perform all class initialization functions (of those which are not |
|
562 yet initialized)." |
|
563 |
|
564 ^ self postLoadActions:true |
|
565 |
|
566 "Modified: 15.8.1997 / 01:02:17 / cg" |
|
567 ! |
|
568 |
|
569 postLoadActions:loadUnresolved |
|
570 "Resolve all classes' string constants. |
|
571 Perform all class initialization functions |
|
572 (of those which are not yet initialized)." |
|
573 |
|
574 |classes prevUnresolved newUnresolved loader| |
|
575 |
|
576 "/ need at least java.lang.String, for valid constants |
|
577 Java java_lang_String isNil ifTrue:[ |
|
578 self loadClassLazy:'java.lang.String' ignoring:(Set new). |
|
579 ]. |
|
580 |
|
581 LazyClassLoading ifFalse:[ |
|
582 loader := ClassLoaderQuerySignal query. |
|
583 |
|
584 prevUnresolved := nil. |
|
585 newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray. |
|
586 loadUnresolved ifTrue:[ |
|
587 [prevUnresolved ~= newUnresolved] whileTrue:[ |
|
588 newUnresolved do:[:nextUnresolved | |
|
589 |classURL| |
|
590 |
|
591 (Java at:nextUnresolved) isNil ifTrue:[ "/ could have been loaded in the meantime |
|
592 Silent ifFalse:[ |
|
593 'loading unresolved: ' print. nextUnresolved printCR. |
|
594 ]. |
|
595 loader isNil ifTrue:[ |
|
596 self |
|
597 loadClassLazy:nextUnresolved |
|
598 ignoring:(Set new). |
|
599 ] ifFalse:[ |
|
600 "/ |
|
601 "/ the aquired loader is a javaClassLoader |
|
602 "/ which expects an URL as arg. |
|
603 "/ |
|
604 "/ classURL := Java as_URL:('file:' , nextUnresolved asString , '.class'). |
|
605 "/ loader loadClass:classURL |
|
606 loader |
|
607 perform:#'loadClass(Ljava/lang/String;)Ljava/lang/Class;' |
|
608 with:(Java as_String:(nextUnresolved asString)). |
|
609 ] |
|
610 ] |
|
611 ]. |
|
612 prevUnresolved := newUnresolved. |
|
613 newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray. |
|
614 ]. |
|
615 ]. |
|
616 false ifTrue:[ |
|
617 newUnresolved size == 0 ifTrue:[ |
|
618 "/ nothing unresolved |
|
619 |
|
620 (classes := Java allClasses) notNil ifTrue:[ |
|
621 "/ init all new classes |
|
622 "/ fetch again - there could be new ones ... |
|
623 |
|
624 classes := Java allClasses. |
|
625 classes do:[:aJavaClass | |
|
626 aJavaClass isInitialized ifFalse:[ |
|
627 Silent ifFalse:[ |
|
628 'performing class initialization of ' print. aJavaClass fullName printCR. |
|
629 ]. |
|
630 aJavaClass classInit |
|
631 ] |
|
632 ] |
|
633 ] |
|
634 ]. |
|
635 ]. |
|
636 ] |
|
637 |
|
638 "Created: / 15.8.1997 / 01:01:44 / cg" |
|
639 "Modified: / 21.10.1998 / 01:18:35 / cg" |
|
640 ! |
|
641 |
|
642 readFile:aFilename ignoring:classesBeingLoaded |
|
643 "reads a class from aFilename and returns it. |
314 "reads a class from aFilename and returns it. |
644 The JavaClass is NOT installed as global and unresolved |
315 The JavaClass is NOT installed as global and unresolved |
645 refs are NOT patched." |
316 refs are NOT patched." |
646 |
317 |
647 |inStream javaClass| |
318 | inStream javaClass | |
648 |
319 |
649 [ |
320 [ inStream := aFilename asFilename readStream. ] on: StreamError |
650 inStream := aFilename asFilename readStream. |
321 do: [ |
651 ] on:StreamError do:[:ex| |
322 :ex | |
652 Logger log: ('no file: ' , aFilename asString) severity: #error facility: 'JVM'. |
323 Logger |
653 self halt. |
324 log: ('no file: ' , aFilename asString) |
654 ^ nil |
325 severity: #error |
655 ]. |
326 facility: 'JVM'. |
656 |
327 self halt. |
657 javaClass := self new readStream:inStream ignoring:classesBeingLoaded. |
328 ^ nil |
658 (javaClass notNil and:[javaClass isJavaClass]) ifTrue:[ |
329 ]. |
659 javaClass setBinaryFilePath:(inStream pathName). |
330 javaClass := self readStream: inStream ignoring: classesBeingLoaded. |
|
331 (javaClass notNil and: [ javaClass isJavaClass ]) ifTrue: [ |
|
332 javaClass setBinaryFilePath: (inStream pathName). |
660 ]. |
333 ]. |
661 inStream close. |
334 inStream close. |
662 |
335 AbsolutelySilent ifFalse: [ |
663 AbsolutelySilent ifFalse:[ |
336 Logger |
664 Logger log: 'loaded class ' , javaClass displayString severity: #info facility: 'JVM'. |
337 log: 'loaded class ' , javaClass displayString |
665 ]. |
338 severity: #info |
666 |
339 facility: 'JVM'. |
667 |
340 ]. |
668 ^ javaClass |
341 ^ javaClass. |
669 |
342 |
670 "Created: / 15-04-1996 / 14:58:53 / cg" |
343 "Created: / 15-04-1996 / 14:58:53 / cg" |
671 "Modified: / 09-05-1998 / 01:44:24 / cg" |
344 "Modified: / 09-05-1998 / 01:44:24 / cg" |
672 "Modified: / 14-09-2011 / 22:20:22 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
345 "Modified: / 14-09-2011 / 22:20:22 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
673 ! |
346 ! |
674 |
347 |
675 readStream:aStream |
|
676 "reads a class from aStream and returns it. |
|
677 The JavaClass is installed as global. |
|
678 If new classes are required to be loaded, a new standard loader |
|
679 is created." |
|
680 |
|
681 ^ self readStream:aStream loader:nil |
|
682 |
|
683 "Modified: 14.8.1997 / 19:51:50 / cg" |
|
684 ! |
|
685 |
|
686 readStream: aStream ignoring: classesBeingLoaded |
348 readStream: aStream ignoring: classesBeingLoaded |
687 "reads a class from aStream and returns it. |
349 "reads a class from aStream and returns it. |
688 The JavaClass is not installed as global" |
350 The JavaClass is not installed as global" |
689 |
351 |
690 | javaClass | |
352 | javaClass | |
691 |
353 |
692 javaClass := JavaClassReader new readStream: aStream ignoring: classesBeingLoaded. |
354 javaClass := JavaClassReader new readStream: aStream |
693 AbsolutelySilent ifFalse: [ |
355 ignoring: classesBeingLoaded. |
694 Logger log: 'loaded class ' , javaClass displayString severity: #info facility: 'JVM'. |
356 Logger |
695 ]. |
357 log: 'loaded class ' , javaClass displayString |
696 ^ javaClass |
358 severity: #info |
|
359 facility: 'JVM'. |
|
360 ^ javaClass. |
697 |
361 |
698 "Modified: / 30-03-1998 / 18:14:40 / cg" |
362 "Modified: / 30-03-1998 / 18:14:40 / cg" |
699 "Modified: / 09-05-2011 / 23:15:30 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
363 "Modified: / 09-05-2011 / 23:15:30 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
700 "Modified: / 14-09-2011 / 22:21:34 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
364 "Modified: / 14-09-2011 / 22:21:34 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
701 ! |
365 ! ! |
702 |
366 |
703 readStream:aStream loader:aClassLoader |
367 !JavaClassReader class methodsFor:'helpers'! |
704 "reads a class from aStream and returns it. |
368 |
705 The JavaClass is installed as global. |
369 getCleanClassNameFrom: className |
706 If new classes are required to be loaded, aClassLoader is |
370 | cleanClassName | |
707 asked to do it. If aClassLoader is nil, a new standard loader |
371 |
708 is created." |
372 cleanClassName := className utf8Encoded. |
709 |
373 (cleanClassName matches: '*\[*') ifTrue: [ |
710 ^ self |
374 cleanClassName := cleanClassName |
711 readStream:aStream |
375 copyFrom: (cleanClassName lastIndexOf: $[) + 1 |
712 loader:aClassLoader |
376 to: cleanClassName size. |
713 loadUnresolved:true |
377 ]. |
714 |
378 (cleanClassName startsWith:$L) ifTrue: [cleanClassName := cleanClassName copyFrom:2 to: cleanClassName size - 1]. |
715 "Modified: 15.8.1997 / 01:00:35 / cg" |
379 (cleanClassName endsWith: '[]') ifTrue: [ |
716 ! |
380 ('oops - loading of ' , className , ' not supported') infoPrintCR. |
717 |
381 self halt: 'should not happen'. |
718 readStream: aStream loader: aClassLoader loadUnresolved: loadUnresolved |
382 ^ nil |
719 "reads a class from aStream and returns it. |
383 ]. |
720 The JavaClass is installed as global. |
384 (cleanClassName includes: $.) ifTrue: [ |
721 If new classes are required to be loaded, aClassLoader is |
385 cleanClassName := cleanClassName asString copyReplaceAll: $. with: $/ |
722 asked to do it. If aClassLoader is nil, a new standard loader |
386 ]. |
723 is created." |
387 ^ cleanClassName. |
724 |
388 ! |
725 | javaClass | |
389 |
726 |
390 makeArrayOf: loadedJavaClass withDimensions: numOfDimensions |
727 ClassLoaderQuerySignal answer: aClassLoader |
391 | arrayClass | |
728 do: |
392 |
729 [ javaClass := self readStream: aStream ignoring: (Set new). |
393 arrayClass := loadedJavaClass. |
730 javaClass notNil |
394 numOfDimensions timesRepeat: [ arrayClass := arrayClass javaArrayClass. ]. |
731 ifTrue: |
395 ^ arrayClass. |
732 [ JavaClassReader postLoadActions: loadUnresolved. |
396 ! ! |
733 Java at: (javaClass fullName asSymbol) put: javaClass. |
397 |
734 JavaUnresolvedConstant resolveFor: javaClass. ]. ]. |
398 !JavaClassReader class methodsFor:'obsolete'! |
735 ^ javaClass |
399 |
736 |
400 resolveClass: aJavaClass |
737 "Created: / 15-08-1997 / 00:59:24 / cg" |
|
738 "Modified: / 23-01-1998 / 17:14:09 / cg" |
|
739 "Modified: / 09-05-2011 / 23:15:23 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
740 "Modified: / 26-07-2011 / 17:21:40 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
741 ! |
|
742 |
|
743 resolveClass:aJavaClass |
|
744 "Resolve a particular classes' constants. |
401 "Resolve a particular classes' constants. |
745 Perform all class initialization functions |
402 Perform all class initialization functions |
746 (of those which are not yet initialized)." |
403 (of those which are not yet initialized)." |
747 |
404 |
748 |loader classToLoad| |
405 | loader classToLoad | |
749 |
406 |
750 LazyClassLoading ifFalse:[ |
407 self breakPoint: #mh. |
751 loader := (aJavaClass classLoader). "/ ? (ClassLoaderQuerySignal raise). |
408 "new resolving does not need this - shouldn't be called at all" |
752 |
409 LazyClassLoading ifFalse: [ |
|
410 loader := (aJavaClass classLoader). |
753 [ |
411 [ |
754 classToLoad := nil. |
412 classToLoad := nil. |
755 aJavaClass constantPool do:[:item | |
413 aJavaClass constantPool do: [ |
756 |itemClass | |
414 :item | |
|
415 | itemClass | |
757 |
416 |
758 itemClass := item class. |
417 itemClass := item class. |
759 itemClass == JavaUnresolvedClassConstant ifTrue:[ |
418 itemClass == JavaUnresolvedClassConstant ifTrue: [ |
760 classToLoad := item className. |
419 classToLoad := item className. |
|
420 |
761 "/ ] ifFalse:[ |
421 "/ ] ifFalse:[ |
762 "/ itemClass == JavaUnresolvedMethodrefConstant ifTrue:[ |
422 "/ itemClass == JavaUnresolvedMethodrefConstant ifTrue:[ |
763 "/self halt. |
423 "/self halt. |
764 "/ ] ifFalse:[ |
424 "/ ] ifFalse:[ |
765 "/ itemClass == JavaUnresolvedInterfaceMethodrefConstant ifTrue:[ |
425 "/ itemClass == JavaUnresolvedInterfaceMethodrefConstant ifTrue:[ |
766 "/self halt. |
426 "/self halt. |
767 "/ ] |
427 "/ ] |
768 "/ ] |
428 "/ ] |
769 ]. |
429 ]. |
770 ]. |
430 ]. |
771 |
431 classToLoad notNil ifTrue: [ |
772 classToLoad notNil ifTrue:[ |
432 loader isNil ifTrue: [ |
773 loader isNil ifTrue:[ |
433 Java javaRegistry classForName: classToLoad. |
774 self |
434 ] ifFalse: [ |
775 loadClassLazy:classToLoad |
|
776 ignoring:(Set new). |
|
777 ] ifFalse:[ |
|
778 "/ |
435 "/ |
779 "/ the aquired loader is a javaClassLoader |
436 "/ the aquired loader is a javaClassLoader |
780 "/ which expects an URL as arg. |
437 "/ which expects an URL as arg. |
781 "/ |
438 "/ |
782 "/ classURL := Java as_URL:('file:' , nextUnresolved asString , '.class'). |
439 "/ classURL := Java as_URL:('file:' , nextUnresolved asString , '.class'). |
783 "/ loader loadClass:classURL |
440 "/ loader loadClass:classURL |
784 loader |
441 loader perform: #'loadClass(Ljava/lang/String;)Ljava/lang/Class;' |
785 perform:#'loadClass(Ljava/lang/String;)Ljava/lang/Class;' |
442 with: (Java as_String: (classToLoad asString)). |
786 with:(Java as_String:(classToLoad asString)). |
|
787 ] |
443 ] |
788 ]. |
444 ]. |
789 classToLoad notNil. |
445 classToLoad notNil. |
790 ] whileTrue. |
446 ] whileTrue. |
791 |
447 aJavaClass isInitialized ifFalse: [ |
792 aJavaClass isInitialized ifFalse:[ |
448 Silent ifFalse: [ |
793 Silent ifFalse:[ |
449 'performing class initialization of ' print. |
794 'performing class initialization of ' print. aJavaClass fullName printCR. |
450 aJavaClass fullName printCR. |
795 ]. |
451 ]. |
796 aJavaClass classInit |
452 aJavaClass classInit |
797 ]. |
453 ]. |
798 ] |
454 ] |
799 |
455 |
800 "Created: / 20.10.1998 / 17:53:22 / cg" |
456 "Created: / 20.10.1998 / 17:53:22 / cg" |
801 "Modified: / 20.10.1998 / 17:59:09 / cg" |
457 "Modified: / 20.10.1998 / 17:59:09 / cg" |
802 ! ! |
|
803 |
|
804 !JavaClassReader class methodsFor:'helpers'! |
|
805 |
|
806 getCleanClassNameFrom: className |
|
807 | cleanClassName | |
|
808 |
|
809 cleanClassName := className utf8Encoded. |
|
810 (cleanClassName matches: '*\[*') ifTrue: [ |
|
811 cleanClassName := cleanClassName |
|
812 copyFrom: (cleanClassName lastIndexOf: $[) + 1 |
|
813 to: cleanClassName size. |
|
814 ]. |
|
815 (cleanClassName startsWith:$L) ifTrue: [cleanClassName := cleanClassName copyFrom:2 to: cleanClassName size - 1]. |
|
816 (cleanClassName endsWith: '[]') ifTrue: [ |
|
817 ('oops - loading of ' , className , ' not supported') infoPrintCR. |
|
818 self halt: 'should not happen'. |
|
819 ^ nil |
|
820 ]. |
|
821 (cleanClassName includes: $.) ifTrue: [ |
|
822 cleanClassName := cleanClassName asString copyReplaceAll: $. with: $/ |
|
823 ]. |
|
824 ^ cleanClassName. |
|
825 ! |
|
826 |
|
827 makeArrayOf: loadedJavaClass withDimensions: numOfDimensions |
|
828 | arrayClass | |
|
829 |
|
830 arrayClass := loadedJavaClass. |
|
831 numOfDimensions timesRepeat: [ arrayClass := arrayClass javaArrayClass. ]. |
|
832 ^ arrayClass. |
|
833 ! ! |
|
834 |
|
835 !JavaClassReader class methodsFor:'mode setting'! |
|
836 |
|
837 useOldClassReader |
|
838 self error: 'Old class reader should not be used anymore!!'. |
|
839 UsedJavaClassReaderClass := JavaClassReader. |
|
840 |
|
841 "Created: / 09-05-2011 / 23:11:04 / Marcel Hlopko <hlopkmar@fel.cvut.cz>" |
|
842 ! ! |
458 ! ! |
843 |
459 |
844 !JavaClassReader methodsFor:'accessing'! |
460 !JavaClassReader methodsFor:'accessing'! |
845 |
461 |
846 constants |
462 constants |