experiments/JavaClassReloaderTests.st
author Marcel Hlopko <marcel.hlopko@gmail.com>
Tue, 01 Oct 2013 23:06:23 +0200
branchdevelopment
changeset 2756 6659925a80a4
parent 2730 272689c14005
child 2759 7d5ffec2f654
permissions -rw-r--r--
tiny fix in reloading tests

"
 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>"
    "Modified: #setUp / 01-10-2013 / 22:59:07 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
    "Modified: #tearDown / 01-10-2013 / 22:59:11 / 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>"
    "Modified: / 01-10-2013 / 22:59:07 / 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>"
    "Modified: / 01-10-2013 / 22:59:11 / 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::                                                                                                                        §'
! !