001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.jci;
019:
020: import java.io.File;
021:
022: import org.apache.commons.io.FileUtils;
023: import org.apache.commons.jci.classes.ExtendedDump;
024: import org.apache.commons.jci.classes.SimpleDump;
025: import org.apache.commons.jci.compilers.CompilationResult;
026: import org.apache.commons.jci.compilers.JavaCompiler;
027: import org.apache.commons.jci.compilers.JavaCompilerSettings;
028: import org.apache.commons.jci.listeners.CompilingListener;
029: import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
030: import org.apache.commons.jci.problems.CompilationProblem;
031: import org.apache.commons.jci.problems.CompilationProblemHandler;
032: import org.apache.commons.jci.readers.ResourceReader;
033: import org.apache.commons.jci.stores.ResourceStore;
034: import org.apache.commons.jci.utils.ConversionUtils;
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037:
038: /**
039: *
040: * @author tcurdt
041: */
042: public final class CompilingClassLoaderTestCase extends
043: AbstractTestCase {
044:
045: private final Log log = LogFactory
046: .getLog(CompilingClassLoaderTestCase.class);
047:
048: private ReloadingClassLoader classloader;
049: private CompilingListener listener;
050: private FilesystemAlterationMonitor fam;
051:
052: private final static class MockJavaCompiler implements JavaCompiler {
053:
054: private final Log log = LogFactory
055: .getLog(MockJavaCompiler.class);
056:
057: public CompilationResult compile(String[] pResourcePaths,
058: ResourceReader pReader, ResourceStore pStore,
059: ClassLoader pClassLoader, JavaCompilerSettings pSettings) {
060:
061: for (int i = 0; i < pResourcePaths.length; i++) {
062: final String resourcePath = pResourcePaths[i];
063: final byte[] resourceContent = pReader
064: .getBytes(resourcePath);
065:
066: log.debug("resource "
067: + resourcePath
068: + " = "
069: + ((resourceContent != null) ? new String(
070: resourceContent) : null));
071:
072: final byte[] data;
073:
074: if ("jci/Simple.java".equals(resourcePath)) {
075:
076: try {
077: data = SimpleDump.dump(new String(
078: resourceContent));
079: } catch (Exception e) {
080: throw new RuntimeException(
081: "cannot handle resource "
082: + resourcePath, e);
083: }
084:
085: } else if ("jci/Extended.java".equals(resourcePath)) {
086:
087: try {
088: data = ExtendedDump.dump();
089: } catch (Exception e) {
090: throw new RuntimeException(
091: "cannot handle resource "
092: + resourcePath, e);
093: }
094:
095: } else {
096: throw new RuntimeException(
097: "cannot handle resource " + resourcePath);
098: }
099:
100: log.debug("compiling " + resourcePath + " ("
101: + data.length + ")");
102:
103: pStore.write(ConversionUtils
104: .stripExtension(resourcePath)
105: + ".class", data);
106:
107: }
108:
109: return new CompilationResult(new CompilationProblem[0]);
110: }
111:
112: public CompilationResult compile(String[] pResourcePaths,
113: ResourceReader pReader, ResourceStore pStore,
114: ClassLoader pClassLoader) {
115: return compile(pResourcePaths, pReader, pStore,
116: pClassLoader, null);
117: }
118:
119: public CompilationResult compile(String[] pResourcePaths,
120: ResourceReader pReader, ResourceStore pStore) {
121: return compile(pResourcePaths, pReader, pStore, null);
122: }
123:
124: public void setCompilationProblemHandler(
125: CompilationProblemHandler pHandler) {
126: }
127:
128: public JavaCompilerSettings createDefaultSettings() {
129: return null;
130: }
131:
132: }
133:
134: protected void setUp() throws Exception {
135: super .setUp();
136:
137: classloader = new ReloadingClassLoader(this .getClass()
138: .getClassLoader());
139: listener = new CompilingListener(new MockJavaCompiler());
140:
141: listener.addReloadNotificationListener(classloader);
142:
143: fam = new FilesystemAlterationMonitor();
144: fam.addListener(directory, listener);
145: fam.start();
146: }
147:
148: private void initialCompile() throws Exception {
149: log.debug("initial compile");
150:
151: listener.waitForFirstCheck();
152:
153: writeFile("jci/Simple.java", "Simple1");
154: writeFile("jci/Extended.java", "Extended");
155:
156: log.debug("waiting for compile changes to get applied");
157: listener.waitForCheck();
158:
159: log.debug("*** ready to test");
160: }
161:
162: public void testCreate() throws Exception {
163: initialCompile();
164:
165: log.debug("loading Simple");
166: final Object simple = classloader.loadClass("jci.Simple")
167: .newInstance();
168: assertEquals("Simple1", simple.toString());
169:
170: log.debug("loading Extended");
171: final Object extended = classloader.loadClass("jci.Extended")
172: .newInstance();
173: assertEquals("Extended:Simple1", extended.toString());
174: }
175:
176: public void testChange() throws Exception {
177: initialCompile();
178:
179: final Object simple = classloader.loadClass("jci.Simple")
180: .newInstance();
181: assertEquals("Simple1", simple.toString());
182:
183: final Object extended = classloader.loadClass("jci.Extended")
184: .newInstance();
185: assertEquals("Extended:Simple1", extended.toString());
186:
187: delay();
188: writeFile("jci/Simple.java", "Simple2");
189: listener.waitForCheck();
190:
191: final Object simple2 = classloader.loadClass("jci.Simple")
192: .newInstance();
193: assertEquals("Simple2", simple2.toString());
194:
195: final Object newExtended = classloader
196: .loadClass("jci.Extended").newInstance();
197: assertEquals("Extended:Simple2", newExtended.toString());
198: }
199:
200: public void testDelete() throws Exception {
201: initialCompile();
202:
203: final Object simple = classloader.loadClass("jci.Simple")
204: .newInstance();
205: assertEquals("Simple1", simple.toString());
206:
207: final Object extended = classloader.loadClass("jci.Extended")
208: .newInstance();
209: assertEquals("Extended:Simple1", extended.toString());
210:
211: listener.waitForCheck();
212:
213: log.debug("deleting source file");
214: assertTrue(new File(directory, "jci/Extended.java").delete());
215:
216: listener.waitForCheck();
217:
218: log.debug("loading Simple");
219: final Object oldSimple = classloader.loadClass("jci.Simple")
220: .newInstance();
221: assertEquals("Simple1", oldSimple.toString());
222:
223: log.debug("trying to loading Extended");
224: try {
225: classloader.loadClass("jci.Extended").newInstance();
226: fail();
227: } catch (final ClassNotFoundException e) {
228: assertEquals("jci.Extended", e.getMessage());
229: }
230:
231: log.debug("deleting whole directory");
232: FileUtils.deleteDirectory(new File(directory, "jci"));
233:
234: listener.waitForCheck();
235:
236: log.debug("trying to loading Simple");
237: try {
238: classloader.loadClass("jci.Simple").newInstance();
239: fail();
240: } catch (final ClassNotFoundException e) {
241: assertEquals("jci.Simple", e.getMessage());
242: }
243:
244: }
245:
246: public void testDeleteDependency() throws Exception {
247: initialCompile();
248:
249: final Object simple = classloader.loadClass("jci.Simple")
250: .newInstance();
251: assertEquals("Simple1", simple.toString());
252:
253: final Object extended = classloader.loadClass("jci.Extended")
254: .newInstance();
255: assertEquals("Extended:Simple1", extended.toString());
256:
257: log.debug("deleting source file");
258: assertTrue(new File(directory, "jci/Simple.java").delete());
259: listener.waitForCheck();
260:
261: log.debug("trying to load dependend class");
262: try {
263: classloader.loadClass("jci.Extended").newInstance();
264: fail();
265: } catch (final NoClassDefFoundError e) {
266: assertEquals("jci/Simple", e.getMessage());
267: }
268:
269: }
270:
271: protected void tearDown() throws Exception {
272: fam.removeListener(listener);
273: fam.stop();
274: super.tearDown();
275: }
276: }
|