src/JavaClassReader.st
branchjk_new_structure
changeset 1026 5badd1d31864
parent 1025 2c9c84bdd863
child 1028 d30cabc12354
equal deleted inserted replaced
1025:2c9c84bdd863 1026:5badd1d31864
   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   
  1991 
  1607 
  1992     "Modified: / 10-05-2011 / 17:09:47 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  1608     "Modified: / 10-05-2011 / 17:09:47 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  1993 !
  1609 !
  1994 
  1610 
  1995 readConstant_String
  1611 readConstant_String
  1996     | string_index  chars  jString |
  1612     | string_index |
  1997 
  1613 
  1998     string_index := inStream nextUnsignedShortMSB: msb.
  1614     string_index := inStream nextUnsignedShortMSB: msb.
  1999     Verbose 
  1615     ^ JavaStringRef2 in: constants withValueAt: string_index.
  2000         ifTrue: 
  1616 
  2001             [ Transcript
  1617     
  2002                 show: 'string; index= ';
  1618     
  2003                 showCR: string_index ].
       
  2004     
       
  2005     "/ resolve here if possible
       
  2006     
       
  2007     string_index < constSlot 
       
  2008         ifTrue: 
       
  2009             [ Java java_lang_String notNil 
       
  2010                 ifTrue: 
       
  2011                     [ chars := (constants at: string_index).
       
  2012                     chars isString ifFalse: [ self halt: 'should not happen' ].
       
  2013                     jString := JavaVM javaStringObjectForString:chars interned:true.
       
  2014                     ^ jString. ] ].
       
  2015     ^ JavaUnresolvedStringConstant 
       
  2016         pool: constants
       
  2017         poolIndex: constSlot
       
  2018         stringIndex: string_index
       
  2019 
       
  2020     "
       
  2021      Verbose := true.
       
  2022      JavaClassReader readFile:'/phys/ibm3/java/lib/java/lang/System.class'"
       
  2023 
       
  2024     "Created: / 15-04-1996 / 15:20:33 / cg"
  1619     "Created: / 15-04-1996 / 15:20:33 / cg"
  2025     "Modified: / 07-05-1998 / 11:42:45 / cg"
  1620     "Modified: / 07-05-1998 / 11:42:45 / cg"
  2026     "Modified: / 13-05-2011 / 17:31:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  1621     "Modified: / 13-05-2011 / 17:31:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  2027     "Modified: / 10-08-2011 / 23:25:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1622     "Modified: / 10-08-2011 / 23:25:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2028 !
  1623 !
  2663 
  2258 
  2664 !JavaClassReader methodsFor:'helpers'!
  2259 !JavaClassReader methodsFor:'helpers'!
  2665 
  2260 
  2666 loadSuperclassIdentifiedBy: something ignoring: classesBeingLoaded 
  2261 loadSuperclassIdentifiedBy: something ignoring: classesBeingLoaded 
  2667     "overriding method, here we expect something to be new JavaClassRef2"
  2262     "overriding method, here we expect something to be new JavaClassRef2"
  2668 
  2263     
  2669     self assert: something isJavaRef
  2264     self assert: something isJavaRef
  2670         message: 'class identifier is not a java reference'.
  2265         message: 'class identifier is not a java reference'.
  2671 
       
  2672     self assert: something isJavaClassRef
  2266     self assert: something isJavaClassRef
  2673         message: 'class identifier is not a java class reference'.
  2267         message: 'class identifier is not a java class reference'.  
  2674 
  2268     (classesBeingLoaded includes: something name) ifTrue: [
  2675     (classesBeingLoaded includes: something fullName) ifTrue: 
  2269         self 
  2676         [self error: 'class we want to load is being loaded and that means something went wrong. tell mh'].
  2270             error: 'class we want to load is being loaded and that means something went wrong. tell mh'
  2677 
  2271     ].
  2678     "Do NOT use >>something resolve<< here, since something
  2272      "hint in case of bug - is parent of something set? surely jv will know more :)" "find out which classloader is used"
  2679      has no owner set and therefore access check will cause DNU.
  2273     ^ Java javaRegistry classForName: something name definedBy: nil.
  2680      Ask JV for details."
       
  2681 
       
  2682     "
       
  2683     ^Java classForName: something javaClassName.
       
  2684     "
       
  2685     ^self class loadClass: something javaClassName.
       
  2686 
  2274 
  2687     "Created: / 18-05-2011 / 14:55:32 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  2275     "Created: / 18-05-2011 / 14:55:32 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
  2688     "Modified: / 31-08-2011 / 21:25:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2276     "Modified: / 31-08-2011 / 21:25:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2689 !
  2277 !
  2690 
  2278