--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/experiments/JavaClassReloaderTests.st Sun Sep 15 01:02:01 2013 +0100
@@ -0,0 +1,402 @@
+"
+ Copyright (c) 2010-2011 Jan Vrany, Jan Kurs & Marcel Hlopko,
+ SWING Research Group, Czech Technical University
+ in Prague
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the 'Software'), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+"
+"{ Package: 'stx:libjava/experiments' }"
+
+TestCase subclass:#JavaClassReloaderTests
+ instanceVariableNames:'testClassLoader'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Languages-Java-Tests-ClassReloading'
+!
+
+!JavaClassReloaderTests class methodsFor:'documentation'!
+
+copyright
+"
+ Copyright (c) 2010-2011 Jan Vrany, Jan Kurs & Marcel Hlopko,
+ SWING Research Group, Czech Technical University
+ in Prague
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the 'Software'), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+"
+!
+
+history
+
+ "Created: #resources / 21-12-2012 / 18:09:27 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests class methodsFor:'resources'!
+
+resources
+
+ ^ Array
+ with: JavaInitializedResource.
+
+ "Created: / 21-12-2012 / 18:09:27 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests methodsFor:'private'!
+
+compile: sourceCode
+ | classes |
+
+ classes := JavaCompiler compile: sourceCode.
+"/ classes do:[:cls|cls classLoader: testClassLoader] .
+ ^classes
+
+ "Created: / 16-12-2012 / 17:02:41 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+ "Modified: / 09-04-2013 / 22:39:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+compileAndRegister: sourceCode
+ |compiledClasses|
+
+ compiledClasses := self compile: sourceCode.
+ ^ self register: compiledClasses.
+
+ "Created: / 16-12-2012 / 16:59:19 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+!
+
+performTest
+
+ JavaClassReader classLoaderQuerySignal answer: testClassLoader do:[
+ super performTest
+ ].
+
+ "Created: / 16-12-2012 / 16:35:01 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+!
+
+register: aClassOrArray
+
+ ^aClassOrArray isArray ifTrue:[
+ JavaVM registry registerClasses: aClassOrArray .
+ JavaVM registry classNamed: aClassOrArray anElement name loader: aClassOrArray anElement classLoader
+ ] ifFalse:[
+ JavaVM registry registerClass: aClassOrArray.
+ JavaVM registry classNamed: aClassOrArray name loader: aClassOrArray classLoader
+ ].
+
+ "Created: / 16-12-2012 / 17:02:04 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+ "Modified: / 09-04-2013 / 22:27:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+testInfrastructure
+
+ |compiledClass|
+
+ self assert: (JavaClassReader classLoaderQuerySignal query = testClassLoader )
+ message: 'tests should run in testClassLoader sandbox'.
+ compiledClass := self compileAndRegister: '
+public class HelloSun {
+
+ public String hello() {
+ return "helloooo";
+ }
+
+}
+'.
+ self assert: compiledClass notNil message: 'Java compiler should be working for these tests to run'.
+ self assert: compiledClass classLoader = testClassLoader message: 'compiled classes should have testClassLoader as their defining cl'.
+ self assert: (JavaVM registry getClassesDefinedBy: testClassLoader) size = 1 message: 'only classes from these tests should use testClassLoader'.
+ self assert: (JavaVM registry getClassesDefinedBy: testClassLoader) anElement == compiledClass message: 'compiled classes should be registered in testClassLoader'.
+
+ "Created: / 16-12-2012 / 16:38:17 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests methodsFor:'running'!
+
+setUp
+ testClassLoader := JAVA java lang ClassLoader new.
+
+ "Created: / 16-12-2012 / 16:32:32 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+!
+
+tearDown
+ JavaVM registry unregisterClassLoader: testClassLoader.
+
+ "Created: / 16-12-2012 / 16:33:31 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests methodsFor:'test helpers'!
+
+callerClass
+ | callerClass |
+ callerClass := (JavaCompiler
+ compile: '
+package classReloadingTests;
+public class Caller {
+ public String callFooToString(Object c) {
+ return c.toString();
+ }
+}
+') anElement.
+ callerClass
+ ifNil: [ self error: 'callerClass is expected to be not nil in these tests' ].
+ ^ callerClass.
+
+ "Created: / 06-12-2012 / 21:41:35 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+ "Modified: / 18-12-2012 / 14:00:12 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+ "Modified: / 04-01-2013 / 14:51:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+compileAndRegisterChangingClassParent
+
+ self compileAndRegister: '
+package classReloadingTests;
+public class ChangingClassParent {
+ public String foo() {
+ return "parent";
+ }
+
+ public String toString() {
+ return "" + foo();
+ }
+}'.
+
+ "Created: / 18-12-2012 / 13:47:32 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests methodsFor:'tests - unloading'!
+
+test_unloading_01
+ "
+ 1) compile class A1 and class A2 inheriting from A1
+ 2) compile class B that instantiates A and call its method A2.bar from B.foo
+ 3) remove class A1 (should remove A2 as well)
+ 4) call B.foo and checks it raises ClassNotFoundException
+ 5) compile class A2
+ 6) call B.foo and checks it returns new value
+ "
+
+ | jclassA1 jclassA2 jclassB jinstB |
+
+ jclassA1 := self compileAndRegister:'
+public class test_unloading_01_A1 {
+ public int bar() {
+ return 1;
+ }
+}'.
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 extends test_unloading_01_A1 {
+}'.
+
+
+ jclassB := self compileAndRegister:'
+public class test_unloading_01_B {
+ public int foo() {
+ return (new test_unloading_01_A2()).bar();
+ }
+}'.
+ jinstB := jclassB new.
+ self assert: jinstB foo == 1.
+ self assert: (Smalltalk allClasses includesIdentical: jclassA1).
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2).
+
+
+ jclassA1 removeFromSystem.
+ self assert: (Smalltalk allClasses includesIdentical: jclassA1) not.
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2) not.
+
+ [
+ jinstB foo.
+ self assert: false "/ should raise ClassNotFoundException
+ ] on: JAVA java lang ClassNotFoundException do:[
+ self assert: true.
+ ].
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 {
+ public int bar() {
+ return 20;
+ }
+}'.
+
+ self assert: jinstB foo == 20.
+
+ "Created: / 14-09-2013 / 18:57:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_unloading_02a
+ "
+ 1) compile interface I1 and class A2 implementing I1
+ 2) compile class B that instantiates A and call its method A2.bar from B.foo
+ 3) remove class I1 (should remove A2 as well)
+ 4) call B.foo and checks it raises ClassNotFoundException
+ 5) compile class A2
+ 6) call B.foo and checks it returns new value
+ "
+
+ | jclassI1 jclassA2 jclassB jinstB |
+
+ jclassI1 := self compileAndRegister:'
+public interface test_unloading_01_I1 {
+ public int bar()
+}'.
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 implements test_unloading_01_I1 {
+ public int bar() { return 1; }
+}'.
+
+
+ jclassB := self compileAndRegister:'
+public class test_unloading_01_B {
+ public int foo() {
+ return (new test_unloading_01_A2()).bar();
+ }
+}'.
+ jinstB := jclassB new.
+ self assert: jinstB foo == 1.
+ self assert: (Smalltalk allClasses includesIdentical: jclassI1).
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2).
+
+
+ jclassI1 removeFromSystem.
+ self assert: (Smalltalk allClasses includesIdentical: jclassI1) not.
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2) not.
+
+ [
+ jinstB foo.
+ self assert: false "/ should raise ClassNotFoundException
+ ] on: JAVA java lang ClassNotFoundException do:[
+ self assert: true.
+ ].
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 {
+ public int bar() {
+ return 20;
+ }
+}'.
+
+ self assert: jinstB foo == 20.
+
+ "Created: / 14-09-2013 / 19:02:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_unloading_02b
+ "
+ 1) compile interface I1, I2, I2 implenting I1, and class A2 implementing I2
+ 2) compile class B that instantiates A and call its method A2.bar from B.foo
+ 3) remove class I1 (should remove A2 as well)
+ 4) call B.foo and checks it raises ClassNotFoundException
+ 5) compile class A2
+ 6) call B.foo and checks it returns new value
+ "
+
+ | jclassI1 jclassI2 jclassA2 jclassB jinstB |
+
+ jclassI1 := self compileAndRegister:'
+public interface test_unloading_01_I1 {
+ public int bar()
+}'.
+
+ jclassI2 := self compileAndRegister:'
+public interface test_unloading_01_I2 extends test_unloading_01_I1 {
+}'.
+
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 implements test_unloading_01_I1 {
+ public int bar() { return 1; }
+}'.
+
+
+ jclassB := self compileAndRegister:'
+public class test_unloading_01_B {
+ public int foo() {
+ return (new test_unloading_01_A2()).bar();
+ }
+}'.
+ jinstB := jclassB new.
+ self assert: jinstB foo == 1.
+ self assert: (Smalltalk allClasses includesIdentical: jclassI1).
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2).
+
+
+ jclassI1 removeFromSystem.
+ self assert: (Smalltalk allClasses includesIdentical: jclassI1) not.
+ self assert: (Smalltalk allClasses includesIdentical: jclassI2) not.
+ self assert: (Smalltalk allClasses includesIdentical: jclassA2) not.
+
+ [
+ jinstB foo.
+ self assert: false "/ should raise ClassNotFoundException
+ ] on: JAVA java lang ClassNotFoundException do:[
+ self assert: true.
+ ].
+
+ jclassA2 := self compileAndRegister:'
+public class test_unloading_01_A2 {
+ public int bar() {
+ return 20;
+ }
+}'.
+
+ self assert: jinstB foo == 20.
+
+ "Created: / 14-09-2013 / 19:04:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-09-2013 / 00:40:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaClassReloaderTests class methodsFor:'documentation'!
+
+version_CVS
+ ^ '$Header: /cvs/stx/stx/libjava/experiments/ClassReloadingTests.st,v 1.2 2013-02-25 11:15:34 vrany Exp $'
+!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+ ^ '§Id:: §'
+! !
+