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.jci.classes.ExtendedDump;
023 import org.apache.commons.jci.classes.SimpleDump;
024 import org.apache.commons.jci.listeners.ReloadingListener;
025 import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028
029 /**
030 *
031 * @author tcurdt
032 */
033 public final class ReloadingClassLoaderTestCase extends AbstractTestCase {
034
035 private final Log log = LogFactory.getLog(ReloadingClassLoaderTestCase.class);
036
037 private ReloadingClassLoader classloader;
038 private ReloadingListener listener;
039 private FilesystemAlterationMonitor fam;
040
041 private final byte[] clazzSimple1;
042 private final byte[] clazzSimple2;
043 private final byte[] clazzExtended;
044
045 public ReloadingClassLoaderTestCase() throws Exception {
046 clazzSimple1 = SimpleDump.dump("Simple1");
047 clazzSimple2 = SimpleDump.dump("Simple2");
048 clazzExtended = ExtendedDump.dump();
049 assertTrue(clazzSimple1.length > 0);
050 assertTrue(clazzSimple2.length > 0);
051 assertTrue(clazzExtended.length > 0);
052 }
053
054 @Override
055 protected void setUp() throws Exception {
056 super.setUp();
057
058 classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
059 listener = new ReloadingListener();
060
061 listener.addReloadNotificationListener(classloader);
062
063 fam = new FilesystemAlterationMonitor();
064 fam.addListener(directory, listener);
065 fam.start();
066 }
067
068 public void testCreate() throws Exception {
069 listener.waitForFirstCheck();
070
071 log.debug("creating class");
072 writeFile("jci/Simple.class", clazzSimple1);
073 listener.waitForCheck();
074
075 final Object simple = classloader.loadClass("jci.Simple").newInstance();
076 assertEquals("Simple1", simple.toString());
077 }
078
079 public void testChange() throws Exception {
080 listener.waitForFirstCheck();
081
082 log.debug("creating class");
083 writeFile("jci/Simple.class", clazzSimple1);
084 listener.waitForCheck();
085
086 final Object simple1 = classloader.loadClass("jci.Simple").newInstance();
087 assertEquals("Simple1", simple1.toString());
088
089 log.debug("changing class");
090 writeFile("jci/Simple.class", clazzSimple2);
091 listener.waitForEvent();
092
093 final Object simple2 = classloader.loadClass("jci.Simple").newInstance();
094 assertEquals("Simple2", simple2.toString());
095 }
096
097 public void testDelete() throws Exception {
098 listener.waitForFirstCheck();
099
100 log.debug("creating class");
101 writeFile("jci/Simple.class", clazzSimple1);
102 listener.waitForCheck();
103
104 final Object simple = classloader.loadClass("jci.Simple").newInstance();
105 assertEquals("Simple1", simple.toString());
106
107 log.debug("deleting class");
108 assertTrue(new File(directory, "jci/Simple.class").delete());
109 listener.waitForEvent();
110
111 try {
112 classloader.loadClass("jci.Simple").newInstance();
113 fail();
114 } catch(final ClassNotFoundException e) {
115 assertEquals("jci.Simple", e.getMessage());
116 }
117 }
118
119 public void testDeleteDependency() throws Exception {
120 listener.waitForFirstCheck();
121
122 log.debug("creating classes");
123 writeFile("jci/Simple.class", clazzSimple1);
124 writeFile("jci/Extended.class", clazzExtended);
125 listener.waitForCheck();
126
127 final Object simple = classloader.loadClass("jci.Simple").newInstance();
128 assertEquals("Simple1", simple.toString());
129
130 final Object extended = classloader.loadClass("jci.Extended").newInstance();
131 assertEquals("Extended:Simple1", extended.toString());
132
133 log.debug("deleting class dependency");
134 assertTrue(new File(directory, "jci/Simple.class").delete());
135 listener.waitForEvent();
136
137 try {
138 classloader.loadClass("jci.Extended").newInstance();
139 fail();
140 } catch(final NoClassDefFoundError e) {
141 assertEquals("jci/Simple", e.getMessage());
142 }
143 }
144
145 public void testClassNotFound() {
146 try {
147 classloader.loadClass("bla");
148 fail();
149 } catch(final ClassNotFoundException e) {
150 }
151 }
152
153 public void testDelegation() {
154 classloader.clearAssertionStatus();
155 classloader.setClassAssertionStatus("org.apache.commons.jci.ReloadingClassLoader", true);
156 classloader.setDefaultAssertionStatus(false);
157 classloader.setPackageAssertionStatus("org.apache.commons.jci", true);
158 // FIXME: compare with delegation
159 }
160
161 @Override
162 protected void tearDown() throws Exception {
163 fam.removeListener(listener);
164 fam.stop();
165 super.tearDown();
166 }
167
168 }