001 /******************************************************************************* 002 * Copyright (C) PicoContainer Organization. All rights reserved. 003 * --------------------------------------------------------------------------- 004 * The software in this package is published under the terms of the BSD style 005 * license a copy of which has been included with this distribution in the 006 * LICENSE.txt file. 007 ******************************************************************************/ 008 package org.picocontainer.script; 009 010 import static org.junit.Assert.assertEquals; 011 import static org.junit.Assert.assertNotNull; 012 import static org.junit.Assert.assertNotSame; 013 import static org.junit.Assert.assertTrue; 014 import static org.junit.Assert.fail; 015 016 import java.io.File; 017 import java.net.MalformedURLException; 018 019 import org.junit.Test; 020 import org.picocontainer.PicoClassNotFoundException; 021 import org.picocontainer.PicoCompositionException; 022 import org.picocontainer.PicoException; 023 import org.picocontainer.classname.ClassLoadingPicoContainer; 024 import org.picocontainer.classname.DefaultClassLoadingPicoContainer; 025 import org.picocontainer.classname.ClassName; 026 import org.picocontainer.script.testmodel.WebServerImpl; 027 028 /** 029 * @author Paul Hammant 030 */ 031 public class ClassNameDefaultClassLoadingPicoContainerTestCase { 032 033 @Test 034 public void testBasic() throws PicoCompositionException { 035 ClassLoadingPicoContainer container = new DefaultClassLoadingPicoContainer(); 036 container.addComponent(new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 037 container.addComponent("org.picocontainer.script.testmodel.WebServer", new ClassName( 038 "org.picocontainer.script.testmodel.WebServerImpl")); 039 } 040 041 @Test 042 public void testProvision() throws PicoException { 043 ClassLoadingPicoContainer container = new DefaultClassLoadingPicoContainer(); 044 container.addComponent(new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 045 container.addComponent(new ClassName("org.picocontainer.script.testmodel.WebServerImpl")); 046 047 assertNotNull("WebServerImpl should exist", container.getComponent(WebServerImpl.class)); 048 assertTrue("WebServerImpl should exist", container.getComponent(WebServerImpl.class) != null); 049 } 050 051 @Test 052 public void testNoGenerationRegistration() throws PicoCompositionException { 053 ClassLoadingPicoContainer container = new DefaultClassLoadingPicoContainer(); 054 try { 055 container.addComponent(new ClassName("Ping")); 056 fail("should have failed"); 057 } catch (PicoClassNotFoundException e) { 058 // expected 059 } 060 } 061 062 @Test 063 public void testThatTestCompIsNotNaturallyInTheClassPathForTesting() { 064 // the following tests try to load the jar containing TestComp - it 065 // won't do to have the class already available in the classpath 066 DefaultClassLoadingPicoContainer dfca = new DefaultClassLoadingPicoContainer(); 067 try { 068 dfca.addComponent("foo", new ClassName("TestComp")); 069 Object o = dfca.getComponent("foo"); 070 fail("Should have failed. Class was loaded from " 071 + o.getClass().getProtectionDomain().getCodeSource().getLocation()); 072 } catch (PicoClassNotFoundException expected) { 073 } 074 075 } 076 077 @Test 078 public void testChildContainerAdapterCanRelyOnParentContainerAdapter() throws MalformedURLException { 079 080 File testCompJar = TestHelper.getTestCompJarFile(); 081 082 // Set up parent 083 ClassLoadingPicoContainer parentContainer = new DefaultClassLoadingPicoContainer(); 084 parentContainer.addClassLoaderURL(testCompJar.toURL()); 085 parentContainer.addComponent("parentTestComp", new ClassName("TestComp")); 086 parentContainer.addComponent(new ClassName("java.lang.StringBuffer")); 087 088 Object parentTestComp = parentContainer.getComponent("parentTestComp"); 089 assertEquals("TestComp", parentTestComp.getClass().getName()); 090 091 // Set up child 092 ClassLoadingPicoContainer childContainer = (ClassLoadingPicoContainer) parentContainer.makeChildContainer(); 093 File testCompJar2 = new File(testCompJar.getParentFile(), "TestComp2.jar"); 094 childContainer.addClassLoaderURL(testCompJar2.toURL()); 095 childContainer.addComponent("childTestComp", new ClassName("TestComp2")); 096 097 Object childTestComp = childContainer.getComponent("childTestComp"); 098 099 assertEquals("TestComp2", childTestComp.getClass().getName()); 100 101 assertNotSame(parentTestComp, childTestComp); 102 103 final ClassLoader parentCompClassLoader = parentTestComp.getClass().getClassLoader(); 104 final ClassLoader childCompClassLoader = childTestComp.getClass().getClassLoader(); 105 if (parentCompClassLoader != childCompClassLoader.getParent()) { 106 printClassLoader(parentCompClassLoader); 107 printClassLoader(childCompClassLoader); 108 fail("parentTestComp classloader should be parent of childTestComp classloader"); 109 } 110 // PicoContainer.getParent() is now ImmutablePicoContainer 111 assertNotSame(parentContainer, childContainer.getParent()); 112 } 113 114 private void printClassLoader(ClassLoader classLoader) { 115 while (classLoader != null) { 116 System.out.println(classLoader); 117 classLoader = classLoader.getParent(); 118 } 119 System.out.println("--"); 120 } 121 122 public static class AnotherFooComp { 123 124 } 125 126 @Test 127 public void testClassLoaderJugglingIsPossible() throws MalformedURLException { 128 ClassLoadingPicoContainer parentContainer = new DefaultClassLoadingPicoContainer(); 129 130 File testCompJar = TestHelper.getTestCompJarFile(); 131 132 parentContainer.addComponent("foo", new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 133 134 Object fooWebServerConfig = parentContainer.getComponent("foo"); 135 assertEquals("org.picocontainer.script.testmodel.DefaultWebServerConfig", fooWebServerConfig.getClass() 136 .getName()); 137 138 ClassLoadingPicoContainer childContainer = new DefaultClassLoadingPicoContainer(parentContainer); 139 childContainer.addClassLoaderURL(testCompJar.toURL()); 140 childContainer.addComponent("bar", new ClassName("TestComp")); 141 142 Object barTestComp = childContainer.getComponent("bar"); 143 assertEquals("TestComp", barTestComp.getClass().getName()); 144 145 assertNotSame(fooWebServerConfig.getClass().getClassLoader(), barTestComp.getClass().getClassLoader()); 146 147 // This kludge is needed because IDEA, Eclipse and Maven have different 148 // numbers of 149 // classloaders in their hierachies for junit invocation. 150 ClassLoader fooCL = fooWebServerConfig.getClass().getClassLoader(); 151 ClassLoader barCL1 = barTestComp.getClass().getClassLoader().getParent(); 152 ClassLoader barCL2, barCL3; 153 if (barCL1 != null && barCL1 != fooCL) { 154 barCL2 = barCL1.getParent(); 155 if (barCL2 != null && barCL2 != fooCL) { 156 barCL3 = barCL2.getParent(); 157 if (barCL3 != null && barCL3 != fooCL) { 158 fail("One of the parent classloaders of TestComp, should be that of DefaultWebServerConfig"); 159 } 160 } 161 } 162 } 163 164 //TODO @Test 165 public void testSecurityManagerCanPreventOperations() throws MalformedURLException { 166 ClassLoadingPicoContainer parentContainer = new DefaultClassLoadingPicoContainer(); 167 168 String testcompJarFileName = System.getProperty("testcomp.jar"); 169 assertNotNull("The testcomp.jar system property does not exist", testcompJarFileName); 170 File testCompJar = new File(testcompJarFileName); 171 assertTrue(testCompJar.isFile()); 172 173 parentContainer.addComponent("foo", new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 174 175 Object fooWebServerConfig = parentContainer.getComponent("foo"); 176 assertEquals("org.picocontainer.script.testmodel.DefaultWebServerConfig", fooWebServerConfig.getClass() 177 .getName()); 178 179 ClassLoadingPicoContainer childContainer = new DefaultClassLoadingPicoContainer(parentContainer); 180 childContainer.addClassLoaderURL(testCompJar.toURL()); 181 // TODO childContainer.setPermission(some permission list, that includes 182 // the preventing of general file access); 183 // Or shoud this be done in the ctor for DRCA ? 184 // or should it a parameter in the addClassLoaderURL(..) method 185 childContainer.addComponent("bar", new ClassName("org.picocontainer.script.testmodel.FileSystemUsing")); 186 187 try { 188 parentContainer.getComponent("bar"); 189 fail("Should have barfed"); 190 } catch (java.security.AccessControlException e) { 191 // expected 192 } 193 } 194 195 }