2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
22
package org.jboss.test.remoting.classloader.race;
24
import java.lang.ref.WeakReference;
25
import java.net.InetAddress;
27
import java.net.URLClassLoader;
28
import java.util.HashMap;
30
import java.util.WeakHashMap;
32
import javax.management.MBeanServer;
34
import junit.framework.TestCase;
36
import org.apache.log4j.ConsoleAppender;
37
import org.apache.log4j.Level;
38
import org.apache.log4j.Logger;
39
import org.apache.log4j.PatternLayout;
40
import org.jboss.logging.XLevel;
41
import org.jboss.remoting.Client;
42
import org.jboss.remoting.InvocationRequest;
43
import org.jboss.remoting.InvokerLocator;
44
import org.jboss.remoting.ServerInvocationHandler;
45
import org.jboss.remoting.ServerInvoker;
46
import org.jboss.remoting.callback.InvokerCallbackHandler;
47
import org.jboss.remoting.transport.Connector;
48
import org.jboss.remoting.transport.PortUtil;
53
* Unit tests for JBREM-900.
55
* Note: The class org.jboss.test.remoting.classloader.race.TestObject mentioned
56
* in the tests below is found in
58
* <remoting home>/src/etc/org/jboss/test/remoting/classloader/race.
62
* <remoting home>/output/tests/classes/org/jboss/test/remoting/classloader/race/test.jar.
64
* @author <a href="ron.sigal@jboss.com">Ron Sigal</a>
65
* @version $Revision: 1.1 $
67
* Copyright Feb 19, 2008
70
public abstract class ClassloaderRaceTestParent extends TestCase
72
private static Logger log = Logger.getLogger(ClassloaderRaceTestParent.class);
74
private static boolean firstTime = true;
75
protected static String metadata;
77
protected String host;
79
protected String locatorURI;
80
protected InvokerLocator serverLocator;
81
protected Connector connector;
82
protected TestInvocationHandler invocationHandler;
85
public void setUp() throws Exception
90
Logger.getLogger("org.jboss.remoting").setLevel(XLevel.INFO);
91
Logger.getLogger("org.jboss.test.remoting").setLevel(Level.INFO);
92
String pattern = "[%d{ABSOLUTE}] [%t] %5p (%F:%L) - %m%n";
93
PatternLayout layout = new PatternLayout(pattern);
94
ConsoleAppender consoleAppender = new ConsoleAppender(layout);
95
Logger.getRootLogger().addAppender(consoleAppender);
96
metadata = System.getProperty("remoting.metadata", "serializationtype=java");
101
public void tearDown()
105
public void testDirectClassloading() throws Throwable
107
log.info("entering " + getName());
109
URL url = ClassloaderRaceTestParent.class.getResource("test.jar");
110
ClassLoader cl1 = new TestClassLoader(new URL[]{url});
111
Class c1 = cl1.loadClass("org.jboss.test.remoting.classloader.race.TestObject");
112
Object testObject1 = c1.newInstance();
113
log.info("classloader1: " + testObject1.getClass().getClassLoader());
115
ClassLoader cl2 = new TestClassLoader(new URL[]{url});
116
Class c2 = cl2.loadClass("org.jboss.test.remoting.classloader.race.TestObject");
117
Object testObject2 = c2.newInstance();
118
log.info("classloader2: " + testObject2.getClass().getClassLoader());
120
assertFalse(testObject1.getClass().isAssignableFrom(testObject2.getClass()));
121
log.info(getName() + " PASSES");
125
public void testSequential() throws Throwable
127
log.info("entering " + getName());
133
InvokerLocator clientLocator = new InvokerLocator(locatorURI);
134
HashMap clientConfig = new HashMap();
135
clientConfig.put(InvokerLocator.FORCE_REMOTE, "true");
136
addExtraClientConfig(clientConfig);
137
Client client = new Client(clientLocator, clientConfig);
139
log.info("client is connected to: " + locatorURI);
141
SimpleInvocationThread t1 = new SimpleInvocationThread(client, "InvocationThread:1");
144
SimpleInvocationThread t2 = new SimpleInvocationThread(client, "InvocationThread:2");
148
assertEquals(t1.getContextClassLoader(), t1.getResponseClassLoader());
149
assertEquals(t2.getContextClassLoader(), t2.getResponseClassLoader());
150
assertNotSame(t1.getResponseClassLoader(), t2.getResponseClassLoader());
154
log.info(getName() + " PASSES");
158
public void testSimultaneous() throws Throwable
160
log.info("entering " + getName());
166
InvokerLocator clientLocator = new InvokerLocator(locatorURI);
167
HashMap clientConfig = new HashMap();
168
clientConfig.put(InvokerLocator.FORCE_REMOTE, "true");
169
addExtraClientConfig(clientConfig);
170
Client client = new Client(clientLocator, clientConfig);
172
log.info("client is connected to: " + locatorURI);
175
log.info("COUNT: " + COUNT);
176
SynchronizedInvocationThread[] threads = new SynchronizedInvocationThread[COUNT];
177
Object lock = new Object();
178
URL url = ClassloaderRaceTestParent.class.getResource("test.jar");
179
ClassLoader cl1 = new TestClassLoader(new URL[]{url});
180
ClassLoader cl2 = new TestClassLoader(new URL[]{url});
181
log.info("classloader1: " + cl1);
182
log.info("classloader2: " + cl2);
184
// Create threads that use cl1.
185
for (int i = 0; i < COUNT / 2; i++)
187
threads[i] = new SynchronizedInvocationThread(client, cl1, i, lock);
191
// Create threads that use cl2.
192
for (int i = COUNT/2; i < COUNT; i++)
194
threads[i] = new SynchronizedInvocationThread(client, cl2, i, lock);
205
// Wait for all threads to complete.
206
for (int i = 0; i < COUNT; i++)
211
// Checks threads that use cl1.
212
for (int i = 0; i < COUNT / 2; i++)
214
assertEquals("error in thread " + i, cl1, threads[i].responseClassLoader);
217
// Check threads that use cl2.
218
for (int i = COUNT / 2; i < COUNT; i++)
220
assertEquals("error in thread " + i, cl2, threads[i].responseClassLoader);
225
log.info(getName() + " PASSES");
229
protected abstract String getTransport();
232
protected void addExtraClientConfig(Map config) {}
233
protected void addExtraServerConfig(Map config) {}
236
protected void setupServer() throws Exception
238
host = InetAddress.getLocalHost().getHostAddress();
239
port = PortUtil.findFreePort(host);
240
locatorURI = getTransport() + "://" + host + ":" + port;
241
locatorURI += "/?" + metadata;
242
serverLocator = new InvokerLocator(locatorURI);
243
log.info("Starting remoting server with locator uri of: " + locatorURI);
244
HashMap config = new HashMap();
245
config.put(InvokerLocator.FORCE_REMOTE, "true");
246
addExtraServerConfig(config);
247
connector = new Connector(serverLocator, config);
249
invocationHandler = new TestInvocationHandler();
250
connector.addInvocationHandler("test", invocationHandler);
255
protected void shutdownServer() throws Exception
257
if (connector != null)
262
static class TestInvocationHandler implements ServerInvocationHandler
264
public void addListener(InvokerCallbackHandler callbackHandler) {}
265
public Object invoke(final InvocationRequest invocation) throws Throwable
267
URL url = ClassloaderRaceTestParent.class.getResource("test.jar");
268
ClassLoader cl1 = new TestClassLoader(new URL[]{url});
269
Class c = cl1.loadClass("org.jboss.test.remoting.classloader.race.TestObject");
270
Object o = c.newInstance();
273
public void removeListener(InvokerCallbackHandler callbackHandler) {}
274
public void setMBeanServer(MBeanServer server) {}
275
public void setInvoker(ServerInvoker invoker) {}
279
static class TestClassLoader extends URLClassLoader
281
public TestClassLoader(URL[] urls)
286
public Class findClass(String fqn) throws ClassNotFoundException
288
log.debug(this + " loading class: " + fqn);
289
Class c = super.findClass(fqn);
290
log.debug(this + " loaded class: " + fqn);
296
static class SimpleInvocationThread extends Thread
300
ClassLoader contextClassLoader;
301
ClassLoader responseClassLoader;
303
public SimpleInvocationThread(Client client, String name)
305
this.client = client;
313
URL url = getClass().getResource("test.jar");
314
contextClassLoader = new TestClassLoader(new URL[]{url});
315
Thread.currentThread().setContextClassLoader(contextClassLoader);
316
log.info(this + " context classloader: " + contextClassLoader);
317
Object response = client.invoke(name);
318
responseClassLoader = response.getClass().getClassLoader();
319
log.info(this + " response classloader: " + responseClassLoader);
323
log.error("unable to complete invocation", t);
327
public ClassLoader getContextClassLoader()
329
return contextClassLoader;
332
public ClassLoader getResponseClassLoader()
334
return responseClassLoader;
337
public String toString()
344
static class SynchronizedInvocationThread extends Thread
348
ClassLoader contextClassLoader;
349
ClassLoader responseClassLoader;
352
public SynchronizedInvocationThread(Client client, ClassLoader classLoader,
355
this.client = client;
356
this.contextClassLoader = classLoader;
357
this.name = "SynchronizedInvocationThread:" + id;
365
Thread.currentThread().setContextClassLoader(contextClassLoader);
369
log.debug(this + " waiting");
373
log.debug(this + " making invocation");
374
Object response = client.invoke(name);
375
responseClassLoader = response.getClass().getClassLoader();
376
log.debug(this + " done");
380
log.error(this + " unable to complete invocation", t);
384
public String toString()
b'\\ No newline at end of file'