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 // System.err.println("--> " + testCompJar2.getAbsolutePath()); 095 childContainer.addClassLoaderURL(testCompJar2.toURL()); 096 childContainer.addComponent("childTestComp", new ClassName("TestComp2")); 097 098 Object childTestComp = childContainer.getComponent("childTestComp"); 099 100 assertEquals("TestComp2", childTestComp.getClass().getName()); 101 102 assertNotSame(parentTestComp, childTestComp); 103 104 final ClassLoader parentCompClassLoader = parentTestComp.getClass().getClassLoader(); 105 final ClassLoader childCompClassLoader = childTestComp.getClass().getClassLoader(); 106 if (parentCompClassLoader != childCompClassLoader.getParent()) { 107 printClassLoader(parentCompClassLoader); 108 printClassLoader(childCompClassLoader); 109 fail("parentTestComp classloader should be parent of childTestComp classloader"); 110 } 111 // PicoContainer.getParent() is now ImmutablePicoContainer 112 assertNotSame(parentContainer, childContainer.getParent()); 113 } 114 115 private void printClassLoader(ClassLoader classLoader) { 116 while (classLoader != null) { 117 System.out.println(classLoader); 118 classLoader = classLoader.getParent(); 119 } 120 System.out.println("--"); 121 } 122 123 public static class AnotherFooComp { 124 125 } 126 127 @Test 128 public void testClassLoaderJugglingIsPossible() throws MalformedURLException { 129 ClassLoadingPicoContainer parentContainer = new DefaultClassLoadingPicoContainer(); 130 131 File testCompJar = TestHelper.getTestCompJarFile(); 132 133 parentContainer.addComponent("foo", new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 134 135 Object fooWebServerConfig = parentContainer.getComponent("foo"); 136 assertEquals("org.picocontainer.script.testmodel.DefaultWebServerConfig", fooWebServerConfig.getClass() 137 .getName()); 138 139 ClassLoadingPicoContainer childContainer = new DefaultClassLoadingPicoContainer(parentContainer); 140 childContainer.addClassLoaderURL(testCompJar.toURL()); 141 childContainer.addComponent("bar", new ClassName("TestComp")); 142 143 Object barTestComp = childContainer.getComponent("bar"); 144 assertEquals("TestComp", barTestComp.getClass().getName()); 145 146 assertNotSame(fooWebServerConfig.getClass().getClassLoader(), barTestComp.getClass().getClassLoader()); 147 148 // This kludge is needed because IDEA, Eclipse and Maven have different 149 // numbers of 150 // classloaders in their hierachies for junit invocation. 151 ClassLoader fooCL = fooWebServerConfig.getClass().getClassLoader(); 152 ClassLoader barCL1 = barTestComp.getClass().getClassLoader().getParent(); 153 ClassLoader barCL2, barCL3; 154 if (barCL1 != null && barCL1 != fooCL) { 155 barCL2 = barCL1.getParent(); 156 if (barCL2 != null && barCL2 != fooCL) { 157 barCL3 = barCL2.getParent(); 158 if (barCL3 != null && barCL3 != fooCL) { 159 fail("One of the parent classloaders of TestComp, should be that of DefaultWebServerConfig"); 160 } 161 } 162 } 163 } 164 165 //TODO @Test 166 public void testSecurityManagerCanPreventOperations() throws MalformedURLException { 167 ClassLoadingPicoContainer parentContainer = new DefaultClassLoadingPicoContainer(); 168 169 String testcompJarFileName = System.getProperty("testcomp.jar"); 170 assertNotNull("The testcomp.jar system property does not exist", testcompJarFileName); 171 File testCompJar = new File(testcompJarFileName); 172 assertTrue(testCompJar.isFile()); 173 174 parentContainer.addComponent("foo", new ClassName("org.picocontainer.script.testmodel.DefaultWebServerConfig")); 175 176 Object fooWebServerConfig = parentContainer.getComponent("foo"); 177 assertEquals("org.picocontainer.script.testmodel.DefaultWebServerConfig", fooWebServerConfig.getClass() 178 .getName()); 179 180 ClassLoadingPicoContainer childContainer = new DefaultClassLoadingPicoContainer(parentContainer); 181 childContainer.addClassLoaderURL(testCompJar.toURL()); 182 // TODO childContainer.setPermission(some permission list, that includes 183 // the preventing of general file access); 184 // Or shoud this be done in the ctor for DRCA ? 185 // or should it a parameter in the addClassLoaderURL(..) method 186 childContainer.addComponent("bar", new ClassName("org.picocontainer.script.testmodel.FileSystemUsing")); 187 188 try { 189 parentContainer.getComponent("bar"); 190 fail("Should have barfed"); 191 } catch (java.security.AccessControlException e) { 192 // expected 193 } 194 } 195 196 }