"
COPYRIGHT (c) 1996-2011 by Claus Gittinger
New code and modifications done at SWING Research Group [1]:
COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
SWING Research Group, Czech Technical University in Prague
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
[1] Code written at SWING Research Group contains a signature
of one of the above copright owners. For exact set of such code,
see the differences between this version and version stx:libjava
as of 1.9.2010
"
"{ Package: 'stx:libjava' }"
Object subclass:#Java
instanceVariableNames:''
classVariableNames:'Classes UnresolvedClassRefs Release ClassPath ClassPathExt
SourceDirectories CacheDirectory JavaHome InternedStrings
Java_lang_String Java_lang_Class PrettyPrintStyle
LastArgumentString Threads ExcludedClassPath FailedToLoadClasses
SourceCache SourceArchiveCache JavaClassLoaderQuerySignal
ClassLoaderQuerySignal'
poolDictionaries:''
category:'Languages-Java-Support'
!
!Java class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1996-2011 by Claus Gittinger
New code and modifications done at SWING Research Group [1]:
COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
SWING Research Group, Czech Technical University in Prague
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
[1] Code written at SWING Research Group contains a signature
of one of the above copright owners. For exact set of such code,
see the differences between this version and version stx:libjava
as of 1.9.2010
"
! !
!Java class methodsFor:'accessing'!
classForName: aString
^JavaVM classForName: aString.
!
classNamed: aString
^JavaVM classNamed: aString.
!
classRegistry
<resource: #obsolete>
self breakPoint: #mh.
self breakPoint: #jv.
^ JavaVM classRegistry.
"Modified: / 21-10-2011 / 11:12:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
intern:aJavaString
|stString internedString|
stString := self as_ST_String:aJavaString.
internedString := InternedStrings at:stString ifAbsent:nil.
internedString isNil ifTrue:[
InternedStrings at:stString put:aJavaString.
internedString := aJavaString
].
^ internedString
!
javaExtDirs
^Java release javaExtDirs
"/ ,{
"/ ((Smalltalk packageDirectoryForPackageId: 'stx:libjava') asFilename
"/ / 'java' / 'libs') }.
"Created: / 31-08-2011 / 22:55:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
java_lang_Class
Java_lang_Class isNil ifTrue:[
Java_lang_Class := self at:'java.lang.Class'
].
^ Java_lang_Class
"Created: 26.3.1997 / 13:42:59 / cg"
"Modified: 26.3.1997 / 13:46:24 / cg"
!
java_lang_String
Java_lang_String isNil ifTrue: [
Java_lang_String := JavaVM classNamed: 'java/lang/String'.
].
^ Java_lang_String.
"Created: / 26-03-1997 / 13:43:17 / cg"
"Modified: / 21-10-2011 / 13:41:02 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!
prettyPrintStyle
^ PrettyPrintStyle
"Created: 1.8.1997 / 10:37:57 / cg"
!
release
^Release
"Created: / 22-11-2010 / 12:38:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
release: aJavaRelease
Release := aJavaRelease.
"
Java release: JavaRelease openJDK6.
Java release: JavaRelease sunJDK6.
"
"Created: / 22-11-2010 / 12:38:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 30-11-2010 / 11:54:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
systemPropertyAt:key put:something
JavaVM systemProperties at:key put:something
"Created: / 9.1.1999 / 14:49:35 / cg"
!
threads
Threads isNil ifTrue:[
Threads := WeakIdentityDictionary new.
].
^ Threads
"Created: 26.8.1997 / 19:53:57 / cg"
"Modified: 26.8.1997 / 19:55:27 / cg"
! !
!Java class methodsFor:'accessing paths'!
addToClassPath:pathOrCollection
| path |
(pathOrCollection isSequenceable
and:[pathOrCollection isCharacters not]) ifTrue:[
pathOrCollection do:[:each|self addToClassPath: each].
^self.
].
path := pathOrCollection asFilename.
(pathOrCollection asString includes: $*) ifTrue:[
self addToClassPathFilesMatching: path baseName
in: path directoryName.
] ifFalse:[
(ClassPath includes:pathOrCollection asString) ifFalse:[
ClassPath add:pathOrCollection asString.
self addToClassPathInRuntime:pathOrCollection.
FailedToLoadClasses := nil
]
]
"Created: / 01-08-1997 / 21:10:07 / cg"
"Modified: / 17-09-1998 / 20:43:55 / cg"
"Modified: / 17-11-2011 / 23:06:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addToClassPathFilesMatching: pattern in: path
| dir |
dir := path asFilename.
dir directoryContents do:
[:fname|
(fname matches: pattern) ifTrue:
[| p |
p := (dir / fname) pathName.
(ClassPath includes:p) ifFalse:
[ClassPath add:p.
self addToClassPathInRuntime:p.
FailedToLoadClasses := nil]]].
"Created: / 20-12-2010 / 17:26:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addToClassPathInRuntime: aPath
| path file url scl |
"Java might not be loaded/or initialized, in this case
there is no no need to inform java about new entry in classpath"
JavaVM booted ifFalse: [ ^ self ].
scl := JavaVM systemClassLoader.
scl isNil ifTrue:[ ^self ].
path := Java as_String: aPath asString.
file := ((JavaVM at: 'java.io.File') new)
perform: #'<init>(Ljava/lang/String;)V' with: path;
yourself.
url := file perform: #'toURL()Ljava/net/URL;'.
scl perform: #'addURL(Ljava/net/URL;)V' with: url.
"Created: / 01-08-1997 / 21:10:07 / cg"
"Modified: / 17-09-1998 / 20:43:55 / cg"
"Created: / 07-08-2011 / 14:01:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
addToSourcePath:pathOrCollection
(pathOrCollection isSequenceable
and:[pathOrCollection isCharacters not]) ifTrue:[
pathOrCollection do:[:each|self addToSourcePath: each].
^self.
].
SourceDirectories ifNil:[SourceDirectories := OrderedCollection new].
(SourceDirectories includes:pathOrCollection) ifFalse:[
SourceDirectories add:pathOrCollection
]
"Created: / 02-08-1997 / 14:12:31 / cg"
"Modified: / 17-11-2011 / 23:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
cacheDirectory
CacheDirectory ifNil:[
CacheDirectory := Filename homeDirectory / '.smalltalk' / 'libjava' / 'caches' /
(((Smalltalk at:#stx_libjava) svnRepositoryUrlBase copyReplaceAll:$/ with:$_) replaceAll:$: with:$_)
].
^CacheDirectory
"Created: / 08-04-2011 / 15:02:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 08-04-2011 / 16:58:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
classPath
| CLASSPATH packagePath |
packagePath := (Smalltalk packageDirectoryForPackageId:'stx:libjava').
CLASSPATH := ((OperatingSystem getEnvironment: 'CLASSPATH') ? '')
tokensBasedOn: OperatingSystem pathSeparator.
^
"for testing only"
"/Release classPath,
{
( packagePath / 'java' / 'libjava-projects' / 'Conversion' / 'bin' ) pathName.
( packagePath / 'java' / 'libjava-support' / 'bin' ) pathName
},
(
(packagePath / 'java' / 'libs') directoryContentsAsFilenames
select:[:f|f suffix = 'jar']
thenCollect:[:f|f pathName]
),
(ClassPath ? #()),
CLASSPATH
"
Java classPath
"
"Created: / 07-02-1997 / 19:23:45 / cg"
"Modified: / 31-08-2011 / 23:23:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
classPath:aCollectionOfPaths
ClassPath := aCollectionOfPaths asOrderedCollection.
FailedToLoadClasses := nil
"Created: / 7.2.1997 / 19:23:45 / cg"
"Modified: / 17.9.1998 / 20:44:09 / cg"
!
effectiveClassPath
ClassPathExt ifNil:[
ClassPathExt := OrderedCollection new.
self javaExtDirs do:[:dir|
dir isDirectory ifTrue:[
dir directoryContentsAsFilenamesDo:[:file|
file suffix = 'jar' ifTrue:[
ClassPathExt add: file pathName
]
]
]
]
].
^self release classPath , "ClassPathExt ," self classPath
"
Java effectiveClassPath
"
"Created: / 22-11-2010 / 13:03:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 17-01-2011 / 09:44:16 / kursjan <kursjan@fit.cvut.cz>"
"Modified: / 31-08-2011 / 23:17:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
effectiveSourceDirectories
^Release sourcePath ,
(SourceDirectories ? #())
"
Java effectiveSourceDirectories
"
"Created: / 30-11-2010 / 11:53:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
excludedClassPath
^ ExcludedClassPath
"Modified: / 7.2.1997 / 19:23:55 / cg"
"Created: / 27.1.1998 / 21:57:13 / cg"
!
isExcludedFromClassPath:fileName
|nm|
nm := fileName asFilename pathName.
ExcludedClassPath do:[:excludedPath |
(nm startsWith:excludedPath) ifTrue:[^ true].
].
^ false
"Created: / 27.1.1998 / 22:00:40 / cg"
!
javaHome
^ JavaHome ifNil:[Release javaHome]
"Created: / 06-08-1997 / 00:53:19 / cg"
"Modified: / 22-11-2010 / 12:39:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
javaHome:aPath
<resource: #obsolete>
self obsoleteMethodWarning: 'javaHome is now controlled by java release'.
JavaHome := aPath
"Created: / 06-08-1997 / 00:53:23 / cg"
"Modified: / 22-11-2010 / 12:40:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
newJavaHome:newJavaHome
self javaHome:newJavaHome.
!
removeFromClassPath:aPath
(ClassPath includes:aPath) ifTrue:[
ClassPath remove:aPath
]
"Modified: 7.2.1997 / 19:23:55 / cg"
"Created: 1.8.1997 / 21:10:21 / cg"
!
removeFromSourcePath:aPath
(SourceDirectories includes:aPath) ifTrue:[
SourceDirectories remove:aPath
]
"Modified: 7.2.1997 / 19:23:55 / cg"
"Created: 2.8.1997 / 14:13:01 / cg"
!
sourceDirectories
^ SourceDirectories
!
sourceDirectories:aCollectionOfPaths
SourceDirectories := aCollectionOfPaths asOrderedCollection
"
Java
sourceDirectories:#(
'/phys/ibm3/java/src'
)
"
!
sourcePath
^ SourceDirectories
"Created: / 16.1.1998 / 13:26:55 / cg"
! !
!Java class methodsFor:'change & update'!
update: what with: param from: sender
what == #restarted ifTrue:[
self reinitialize.
]
"Created: / 14-12-2010 / 21:00:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Java class methodsFor:'class initialization'!
initAllClasses
| system |
FailedToLoadClasses := nil.
self initAllStaticFields.
system := JavaVM classForName: 'java.lang.System'.
system isInitialized ifFalse: [ self initSystemClass. ].
self allClassesDo: [:cls | cls isInitialized ifFalse: [ cls classInit ] ]
"
Java initAllClasses"
"Modified: / 27.11.1998 / 00:33:05 / cg"
!
initAllStaticFields
self allClassesDo:[:cls |
cls initializeStaticFields
]
!
initSystemClass
| system |
system := JavaVM classForName: 'java.lang.System'.
system isNil ifTrue: [
"/ JavaVM initializeVM.
"/ system := Java at:'java.lang.System'.
"/ system isNil ifTrue:[
self warn: 'JavaVM: no ''' , 'java.lang.System' allBold , ''' class.'.
"/ self error:'no ''java.lang.System'' class'.
^
"/ ].
self
].
system classInit.
(system implements: #'initializeSystemClass()V') ifTrue: [
system "invokeStatic:" perform: #'initializeSystemClass()V'.
].
"
Java initSystemClass
(Java at:'java.lang.System')
perform:#'getProperty(Ljava/lang/String;)Ljava/lang/String;'
with:(Java as_String:'java.home')"
"Modified: / 10.11.1998 / 12:39:58 / cg"
!
initialize
JavaNativeMethod flushAllCachedNativeMethods.
InternedStrings := Dictionary new.
FailedToLoadClasses := nil.
ClassPath := OrderedCollection new.
ClassPathExt := nil.
ExcludedClassPath := OrderedCollection new.
SourceCache := CacheDictionary new: 32.
SourceArchiveCache := CacheDictionary new: 32.
self initializeRelease. "lazy initialization of Release"
self initializePrettyPrintStyle.
ObjectMemory addDependent: self.
"
Java flushAllJavaResources.
Java initialize.
JavaVM initializeVM
Java classPath inspect"
"Modified: / 06-11-2001 / 09:24:12 / cg"
"Created: / 03-10-2010 / 15:54:02 / Jan Kurs <kurs.jan@post.cz>"
"Modified: / 15-10-2010 / 17:37:20 / Jan Kurs <kurs.jan@post.cz>"
"Modified: / 31-08-2011 / 22:50:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
initializePrettyPrintStyle
PrettyPrintStyle := IdentityDictionary new.
PrettyPrintStyle at:#accessAttribute put:(#color -> (Color red:0 green:0 blue:25)).
PrettyPrintStyle at:#className put:(Array with:(#color -> Color black) with:#bold).
PrettyPrintStyle at:#methodName put:(Array with:(#color -> Color black) with:#bold).
PrettyPrintStyle at:#code put:(#color -> Color black).
"
Java initializePrettyPrintStyle
"
"Created: 1.8.1997 / 11:08:43 / cg"
"Modified: 1.8.1997 / 11:09:58 / cg"
!
initializeRelease
Release ifNil:[Release := JavaRelease any].
"
Release := nil.
self initializeRelease.
Release
"
"Created: / 22-11-2010 / 13:41:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
reinitAllClasses
self markAllClassesUninitialized.
self initAllClasses
"
Java reinitAllClasses
"
"Modified: / 4.1.1998 / 00:34:29 / cg"
!
reinitialize
"/ all JavaThreads are lost on a restart (for now)
FailedToLoadClasses := nil.
Threads := nil.
"Kludge"
JavaMethod reinitialize.
JavaMethodWithException reinitialize.
JavaMethodWithHandler reinitialize.
JavaNativeMethod reinitialize.
JavaNativeMethod flushAllCachedNativeMethods.
"
Java reinitialize
"
"Created: / 26-08-1997 / 20:07:00 / cg"
"Modified: / 27-04-1998 / 14:57:23 / cg"
"Modified: / 14-12-2010 / 21:30:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
startupJavaSystem
|javaEventThread haveEventThread haveScreenUpdater|
FailedToLoadClasses := nil.
"/
"/ check if already running
"/
haveEventThread := true.
javaEventThread := JavaVM javaEventThread.
(javaEventThread isNil or:[javaEventThread isDead]) ifTrue:[
haveEventThread := false
].
haveScreenUpdater := false.
haveEventThread ifTrue:[
self threads do:[:aJavaThread |
aJavaThread name = 'JAVA-Screen Updater' ifTrue:[
aJavaThread isDead ifFalse:[
"/ already running
haveScreenUpdater := true
]
]
].
].
(haveEventThread and:[haveScreenUpdater]) ifTrue:[
^ self
].
JavaClass orderOfClassInits isNil ifTrue:[
"/ the very first start ...
'JAVA [info]: (re)initializing JAVA environment completely ...' infoPrintCR.
JavaVM initializeVM.
] ifFalse:[
JavaVM initializeVMIfNoEventThreadRunning
].
'JAVA [info]: done JAVA initialization.' infoPrintCR.
"
Java startupJavaSystem
"
"Modified: / 24.12.1999 / 01:37:49 / cg"
!
terminateAllThreads
| myself threadsToKill semaphore |
Threads isNil ifTrue: [ ^ self ].
myself := Processor activeProcess.
threadsToKill := IdentitySet new.
Threads do: [
:aJavaThread |
aJavaThread ~~ myself ifTrue: [
(aJavaThread isNil or: [ aJavaThread == 0 ]) ifFalse: [
(aJavaThread isMemberOf: JavaProcess) ifTrue: [
aJavaThread isDead ifFalse: [ threadsToKill add: aJavaThread ]
]
]
]
].
threadsToKill size > 0 ifTrue: [
Logger
log: 'Killing ' , threadsToKill size printString , ' java processes'
severity: #info
facility: #JVM.
semaphore := Semaphore new: 1 - threadsToKill size.
semaphore name: 'Java thread killer'.
threadsToKill do: [
:aThread |
aThread == JavaVM javaScreenUpdaterThread ifTrue: [ self halt ].
aThread == JavaVM javaEventQueueThread ifTrue: [ self halt ].
aThread
addExitAction: [
Logger
log: 'Java thread killed successfully'
severity: #info
facility: #JVM.
semaphore signal
].
aThread terminate
].
semaphore wait.
].
JavaVM releaseAllMonitors.
Logger
log: 'No Java threads running at this point'
severity: #info
facility: #JVM.
Threads := nil.
"
Java terminateAllThreads"
"Created: / 26-08-1997 / 19:57:40 / cg"
"Modified: / 24-12-1999 / 02:34:53 / cg"
"Modified: / 17-11-2011 / 21:31:14 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !
!Java class methodsFor:'debugging'!
dontHaltOnKnownBugs
Object disableBreakPoint: #knownBugs.
"Created: / 09-10-2011 / 17:29:17 / m"
!
haltOnKnownBugs
Object enableBreakPoint: #knownBugs.
"Created: / 09-10-2011 / 17:29:05 / m"
! !
!Java class methodsFor:'enumerating'!
allClasses
^JavaVM classRegistry classes
"Modified: / 28-01-1998 / 01:42:04 / cg"
"Modified: / 23-10-2011 / 20:14:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
allClassesDo:aBlock
^JavaVM classRegistry classesDo: aBlock
"Modified: / 23-10-2011 / 20:14:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Java class methodsFor:'object conversions'!
as_Float:aNumber
"convert an ST-float into a Java Float"
|i|
i := (Java at:'java.lang.Float') new.
i perform:#'<init>(F)V' with:(aNumber asShortFloat).
^ i
"
Java as_Float:1
Java as_Float:3.14159
"
"Created: 7.8.1997 / 21:21:13 / cg"
"Modified: 7.8.1997 / 21:22:05 / cg"
!
as_Hashtable: aDictionary
"given a smalltalk dictionary, create and return
a Java hashTable for it"
| hashTable |
hashTable := (JavaVM classForName: 'java.util.Hashtable') new.
aDictionary
keysAndValuesDo: [
:k :v |
| sk sv jk jv |
(sk := k) isSymbol ifTrue: [ sk := sk asString ].
(sv := v) isSymbol ifTrue: [ sv := sv asString ].
jk := self as_Object: sk.
jv := self as_Object: sv.
hashTable
perform: #'put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;'
with: jk
with: jv.
].
^ hashTable
"
Java as_Hashtable:(Dictionary new
at:'hello' put:'Hallo';
at:'world' put:'Welt';
yourself)"
"Modified: / 14.1.1998 / 17:02:13 / cg"
!
as_Integer:anInteger
"convert an ST-integer into a Java Integer"
|i|
i := (Java at:'java.lang.Integer') new.
i perform:#'<init>(I)V' with:anInteger.
^ i
"
Java as_Integer:1
"
"Modified: 7.8.1997 / 21:19:37 / cg"
"Created: 7.8.1997 / 21:21:13 / cg"
!
as_Object:anObject
"convert an ST-Object into a Java Object"
anObject isString ifTrue:[
^ self as_String:anObject
].
anObject isInteger ifTrue:[
^ self as_Integer:anObject
].
self halt.
"
Java as_Object:'hello world'
"
"Created: 7.8.1997 / 21:15:38 / cg"
"Modified: 7.8.1997 / 21:20:07 / cg"
!
as_ST_String: aJavaString
"hard-coding internas of java.lang.String here is bad ..."
| str count offs start stop |
aJavaString isNil ifTrue: [ ^ nil ].
"/ count := aJavaString instVarNamed:'count'.
count := aJavaString instVarAt: 3.
"/ str := aJavaString instVarNamed:'value'
str := aJavaString instVarAt: 1.
str size == count
ifTrue:
[ "cos I don't see any reason to do this"
"/ ^ str asOneByteString.
^ str ].
"/ offs := (aJavaString instVarNamed:'offset').
offs := aJavaString instVarAt: 2.
"/ start := offs + 1.
start := offs + 1.
"/ stop := start + (aJavaString instVarNamed:'count') - 1.
stop := start + count - 1.
"/ ^ ((aJavaString instVarNamed:'value') copyFrom:start to:stop) asString
^ (str copyFrom: start to: stop) asOneByteString
"Created: / 08-08-1997 / 12:02:55 / cg"
"Modified: / 04-01-1999 / 23:55:08 / cg"
"Modified: / 22-03-2011 / 17:21:19 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
"Modified: / 10-08-2011 / 23:32:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
as_String:aString
"convert an ST-String into a Java String"
"hard-coding internas of java.lang.String here is bad ..."
|s|
s := self java_lang_String basicNew.
s instVarNamed:'value' put: aString.
s instVarNamed:'offset' put: 0.
s instVarNamed:'count' put: aString size.
s instVarNamed:'hash' put: 0.
^ s
"
Java as_String:'hello world'
"
"Created: / 07-08-1997 / 21:15:49 / cg"
"Modified: / 03-02-2011 / 23:33:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
as_URL:aString
"convert an ST-String into a Java String"
"hard-coding internas of java.lang.String here is bad ..."
|u s|
s := aString.
"/ kludge for volume
OperatingSystem isMSDOSlike ifTrue:[
((s size > 1) and:[(s at:2) == $:]) ifTrue:[
s := 'file:' , (s copy at:2 put:$|)
]
].
u := (self at:'java.net.URL') newCleared.
u perform:#'<init>(Ljava/lang/String;)V' with:(self as_String:s).
^ u
"
Java as_URL:'http://www.altavista.com'
Java as_URL:'file:/foo/bar'
"
"Created: / 7.8.1997 / 21:15:49 / cg"
"Modified: / 25.9.1999 / 22:22:21 / cg"
! !
!Java class methodsFor:'queries'!
smalltalkClassFor:typeRef
self halt.
"/ (typeString startsWith:'[[') ifTrue:[
"/ ^ Array
"/ ].
"/ (typeString startsWith:'[F') ifTrue:[
"/ ^ FloatArray
"/ ].
self halt.
"Modified: 7.4.1997 / 13:33:46 / cg"
!
smalltalkDerefType:typeString
(typeString startsWith:'[') ifTrue:[
^ typeString copyFrom:2
].
self halt.
"Modified: 7.4.1997 / 13:13:24 / cg"
! !
!Java class methodsFor:'registering java classes'!
at: aJavaName
^JavaVM at: aJavaName.
"Modified: / 18-07-1998 / 22:55:16 / cg"
"Modified (format): / 21-10-2011 / 10:40:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
at: aJavaName put: aJavaClass
^JavaVM at:aJavaName put:aJavaClass.
"Created: / 17-04-1996 / 23:29:31 / cg"
"Modified: / 07-08-1997 / 19:15:58 / cg"
"Modified (format): / 21-10-2011 / 10:39:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
flushAllJavaResources
self flushClasses.
SourceCache := CacheDictionary new: 32.
SourceArchiveCache := CacheDictionary new: 32.
Smalltalk garbageCollect.
ObjectMemory
allObjectsDo: [
:someObject |
someObject isBehavior ifTrue: [
someObject isJavaClass ifTrue: [
someObject setConstantPool: nil.
someObject setInterfaces: nil.
someObject setMethodDictionary: (MethodDictionary new).
Logger
log: 'flushing ' , someObject fullName
severity: #info
facility: 'JVM'.
]
].
].
JavaClass flushClassesInitOrder.
self flushClasses
"
Java flushAllJavaResources"
"Modified: / 06-11-2001 / 09:49:37 / cg"
"Modified: / 02-11-2011 / 21:34:13 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
"Modified: / 14-11-2011 / 19:49:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
flushClasses
UnresolvedClassRefs := nil.
JavaVM flushClasses.
Smalltalk keys copy do:[:aKey |
(aKey startsWith:'JAVA::') ifTrue:[ Smalltalk removeKey:aKey ]
].
Smalltalk removeKey:#'JAVA'.
Java_lang_String := Java_lang_Class := nil.
JavaVM releaseAllJavaResources.
JavaUnresolvedConstant flushPatchLists.
Debugger == DebugView ifTrue:[Debugger newDebugger].
ObjectMemory flushCaches.
"
Java flushClasses
"
"Modified: / 06-11-2001 / 09:47:49 / cg"
"Modified: / 30-10-2011 / 16:09:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 16-11-2011 / 09:43:13 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!
markAllClassesUninitialized
self allClassesDo:[:aJavaClass |
aJavaClass markUninitialized
].
"
Java markAllClassesUninitialized
"
!
rememberUnresolved:anUnresolvedClassRef
('JAVA: remember unresolved class: ' , anUnresolvedClassRef fullName) infoPrintCR.
UnresolvedClassRefs isNil ifTrue:[
UnresolvedClassRefs := Dictionary new.
].
UnresolvedClassRefs
at:anUnresolvedClassRef fullName
put:anUnresolvedClassRef
"Created: / 18.4.1996 / 00:05:31 / cg"
"Modified: / 19.10.1998 / 20:57:44 / cg"
!
removeClass:aJavaClass
"/ remove it from myself
|javaName sym nm cls p ns|
self breakPoint: #jv.
self breakPoint: #mh.
javaName := aJavaClass fullName.
sym := javaName asSymbolIfInterned.
sym notNil ifTrue:[
cls := Classes at:sym ifAbsent:nil.
].
cls isNil ifTrue:[
nm := javaName.
(nm includes:$.) ifTrue:[
"/
"/ try pckg/.../name
"/
nm := (nm asString copyReplaceAll:$. with:$/).
sym := nm asSymbolIfInterned.
sym notNil ifTrue:[
cls := Classes at:sym ifAbsent:nil.
].
].
].
(cls notNil and:[cls == aJavaClass]) ifTrue:[
Classes removeKey:sym.
self updateClassRefsFrom:aJavaClass to:nil.
].
Smalltalk removeKey:('JAVA::' , javaName) asSymbol.
Smalltalk removeKey:javaName asSymbol.
Smalltalk removeKey:((javaName , '') copy replaceAll:$/ with:$.) asSymbol.
"/ remove myself from the JAVA::-::-:: namespace
"/ (which exists for convenient smalltalk access only)
p := aJavaClass nameSpacePath.
p knownAsSymbol ifTrue:[
ns := Smalltalk at:p asSymbol.
(ns notNil and:[ns isNameSpace]) ifTrue:[
Smalltalk removeKey:(p , '::' , aJavaClass lastName) asSymbol
]
].
"Modified: / 19-10-1998 / 20:58:49 / cg"
"Modified (format): / 23-10-2011 / 20:18:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
unresolvedClassRefFor:aClassName
UnresolvedClassRefs isNil ifTrue:[^ nil].
^ UnresolvedClassRefs at:aClassName ifAbsent:nil.
"Modified: / 19.10.1998 / 20:56:46 / cg"
!
updateClassRefsFrom:oldClass to:newClass
"update all references to oldClass to now refer to newClass.
sent, when a class is reloaded"
newClass notNil ifTrue:[
"/
"/ kludge: the new class might have been resolved with the oldClass ...
"/
newClass constantPool
updateClassRefsFrom:oldClass to:newClass.
].
self allClassesDo:[:aJavaClass |
aJavaClass updateClassRefsFrom:oldClass to:newClass
].
"Created: 26.3.1997 / 13:49:20 / cg"
"Modified: 12.8.1997 / 03:04:44 / cg"
! !
!Java class methodsFor:'source management'!
classSource:filename package:package in:dirOrZipFile
|fn zar f |
fn := dirOrZipFile asFilename.
fn isDirectory
ifTrue:
[ package notNil
ifTrue:[ (f:= fn / package / filename) exists ifTrue:[ ^ f contents asString ]. ].
(f := fn / filename) exists ifTrue:[ ^ f contents asString ]. ]
ifFalse:
[ (dirOrZipFile last == $p and: [fn hasSuffix:'zip'])
ifTrue:
[ zar := SourceArchiveCache
at: dirOrZipFile
ifAbsentPut:[ZipArchive oldFileNamed:fn pathName].
zar notNil
ifTrue:
[ package notNil
ifTrue:[
OperatingSystem fileSeparator ~~ $/ ifTrue: [
f := (package copyReplaceAll: OperatingSystem fileSeparator with: $/) , '/' , filename
] ifFalse:[
f := package , '/' , filename.
]]
ifFalse:[ f := filename].
(zar findMember: f) ifNotNil:
[
"Kludge because of broken ZipArchive"
| cache |
cache := Java cacheDirectory / Release name / 'src'.
cache exists ifFalse:[cache recursiveMakeDirectory].
(cache / f) exists ifTrue:[^(cache / f) contents asString].
OperatingSystem
executeCommand:('unzip "%1" "%2"' bindWith: fn asAbsoluteFilename asString
with: f asString)
inDirectory: cache asString.
(f := cache / f) exists ifTrue:[^f contents asString]
]
]]].
^ nil
"
Java classSource: 'Object.java' package:'java/lang' in:'/home/jv/Projects/JavaX/java-6-openjdk/src'
Java classSource: 'Object.java' package:'java/lang' in:'/usr/lib/jvm/java-6-openjdk/src.zip'
"
"Modified: / 29-03-1998 / 21:46:40 / cg"
"Created: / 30-11-2010 / 12:32:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 08-04-2011 / 15:01:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
classSourceOf:aClass
|package dirName binary sourceFileName sourceFile loader codeBaseURL protocol codeBaseURLIdx src|
aClass isNil ifTrue:[
^ nil
].
"/ look at the cache"
SourceCache at: aClass ifPresent: [:src|^src].
"/ first, look in the directory, where the binary
"/ was loaded from.
binary := aClass binaryFile.
binary notNil ifTrue:[
binary := binary asFilename.
aClass sourceFile notNil ifTrue:[
sourceFileName := binary directory constructString:(aClass sourceFile).
sourceFileName asFilename exists ifFalse:[
sourceFileName := nil.
]
].
sourceFileName isNil ifTrue:[
sourceFileName := binary withSuffix:'java'.
].
sourceFile := sourceFileName asFilename.
] ifFalse:[
"/ maybe it was loaded by a java classLoader ...
(loader := aClass classLoader) notNil ifTrue:[
codeBaseURLIdx := loader class instVarOffsetOf:'codeBaseURL'.
codeBaseURLIdx notNil ifTrue:[
(codeBaseURL := loader instVarAt:codeBaseURLIdx) notNil ifTrue:[
(protocol := codeBaseURL instVarNamed:'protocol') notNil ifTrue:[
(Java as_ST_String:protocol) = 'file' ifTrue:[
dirName := Java as_ST_String:(codeBaseURL instVarNamed:'file').
dirName := dirName asFilename.
dirName exists ifTrue:[
aClass sourceFile notNil ifTrue:[
sourceFile := sourceFileName := dirName construct:aClass sourceFile.
]
]
]
]
]
]
]
].
sourceFile notNil ifTrue:[
sourceFile exists ifFalse:[
binary notNil ifTrue:[
sourceFileName := binary withSuffix:'jav'.
sourceFile := sourceFileName asFilename.
sourceFile exists ifFalse:[
sourceFileName := binary withSuffix:'JAV'.
sourceFile := sourceFileName asFilename.
sourceFile exists ifFalse:[
sourceFileName := binary withSuffix:'JAVA'.
sourceFile := sourceFileName asFilename.
].
].
]
].
].
"/ special case: there were multiple classes in a single
"/ source file.
(binary notNil and:[aClass sourceFile notNil]) ifTrue:[
binary withoutSuffix baseName ~= aClass sourceFile asFilename withoutSuffix baseName ifTrue:[
'JAVA: trouble extracting fileName: ' infoPrint.
binary withoutSuffix baseName print. ' vs. ' infoPrint.
aClass sourceFile asFilename withoutSuffix baseName infoPrintCR.
].
].
"/ if that fails, look in standard places
(sourceFile isNil or:[sourceFile exists not]) ifTrue:[
sourceFile := aClass sourceFile.
package := aClass javaPackageAsDirname.
self effectiveSourceDirectories do:[:dir|
src := self classSource: sourceFile package: package in: dir.
src ifNotNil:[^src]
]
].
sourceFile isFilename ifFalse:[^nil].
^ (sourceFile contentsOfEntireFile).
"
Java classSourceOf: JAVA::java::lang::Object
"
"Modified: / 27-01-1999 / 20:40:30 / cg"
"Modified: / 10-02-2011 / 23:10:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!Java class methodsFor:'starting apps'!
javaProcessForMainOf:aJavaClass
"ask for a commandLine, create a java process to invoke
its main and return it. The process is not scheduled for
execution."
^ self javaProcessForMainOf:aJavaClass argumentString:nil
"Modified: / 30.12.1998 / 20:24:25 / cg"
!
javaProcessForMainOf:aJavaClass argumentString:argStringIn
"create a java process, ready to invoke the classes main
method. Returns the process - ready to run but not yet resumed"
|p argStringArray argString stdInReplacement alreadyAskedForStdin|
argString := argStringIn.
argString isNil ifTrue:[
argString := Dialog
request:'argument string:'
initialAnswer:LastArgumentString ? ''
onCancel:nil.
argString isNil ifTrue:[^ nil].
LastArgumentString := argString.
].
JavaVM initializeVMIfNoEventThreadRunning.
(Java at:'java.lang.System') instVarNamed:'security' put:nil.
argString isEmpty ifTrue:[
argStringArray := #()
] ifFalse:[
argStringArray := argString asCollectionOfWords collect:[:s | Java as_String:s] as:Array.
].
p := JavaProcess
for:[
"/ if the program reads from stdin, let user provide a file
"/ for it.
JavaVM stdinReplacementFileQuerySignal handle:[:ex |
|fn|
alreadyAskedForStdin == true ifFalse:[
fn := Dialog
requestFileName:'Program reads from Stdin - give inputFile or cancel for EOF'
default:nil
fromDirectory:(FileSelectionBox lastFileSelectionDirectory).
fn notNil ifTrue:[
stdInReplacement := fn asFilename readStream.
].
alreadyAskedForStdin := true.
].
ex proceedWith:stdInReplacement
] do:[
aJavaClass
performStatic:#'main([Ljava/lang/String;)V'
with:argStringArray.
]
]
priority:(Processor activePriority - 1).
p name:(aJavaClass fullName , '::main()').
p restartable:true.
^ p
"Created: / 15.8.1997 / 04:41:20 / cg"
"Modified: / 24.12.1999 / 01:50:21 / cg"
! !
!Java class methodsFor:'documentation'!
version
^ '$Id$'
!
version_SVN
^ '$Id$'
! !
Java initialize!