24 import java.lang.ref.WeakReference;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.InvocationTargetException;
29 import java.io.PrintWriter;
31 import java.io.FileInputStream;
32 import java.io.IOException;
33 import java.io.FileNotFoundException;
37 import java.net.MalformedURLException;
38 import java.net.URISyntaxException;
39 import java.net.URLClassLoader;
41 import java.nio.ByteBuffer;
42 import java.nio.channels.FileChannel;
77 static protected final PrintWriter
out =
new PrintWriter(System.out,
true);
82 static protected final PrintWriter
err =
new PrintWriter(System.err,
true);
86 boolean assertsEnabled =
false;
87 assert assertsEnabled =
true;
88 if (!assertsEnabled) {
89 throw new RuntimeException(
"Asserts must be enabled for this test to be effective!");
93 static final String pprefixes_prop
94 =
"com.mysql.jtie.test.MyLoadUnloadTest.target_package_prefixes";
95 static final String cname_prop
96 =
"com.mysql.jtie.test.MyLoadUnloadTest.target_class_name";
97 static final String mname_prop
98 =
"com.mysql.jtie.test.MyLoadUnloadTest.target_method_name";
103 static protected WeakReference<ClassLoader>
cl = null;
108 static private final Runtime rt = Runtime.getRuntime();
115 static class SelfishFileClassLoader
extends ClassLoader {
117 public SelfishFileClassLoader() {
118 out.println(
"--> SelfishFileClassLoader()");
119 out.println(
" this = " +
this);
120 out.println(
" getParent() = " + getParent());
121 out.println(
"<-- SelfishFileClassLoader()");
124 private ByteBuffer getClassData(
String name)
125 throws ClassNotFoundException {
126 out.println(
"--> SelfishFileClassLoader.getClassData(String)");
136 String rname = name.replace(
'.',
'/') +
".class";
139 final URL url = ClassLoader.getSystemResource(rname);
141 final String msg = (
"no definition of the class "
142 + rname +
" could be found.");
143 throw new ClassNotFoundException(msg);
145 out.println(
" url = " + url);
151 }
catch (URISyntaxException ex) {
152 final String msg = (
"the URL " + url +
" is not formatted"
153 +
"strictly according to RFC2396 and "
154 +
"cannot be converted to a URI.");
155 throw new ClassNotFoundException(msg, ex);
162 }
catch (IllegalArgumentException ex) {
163 final String msg = (
"the system-dependent URI " + uri
164 +
" cannot be converted into a pathname.");
165 throw new ClassNotFoundException(msg, ex);
170 final String msg = (
"cannot read file " + f);
171 throw new ClassNotFoundException(msg);
173 out.println(
" can read file " + f);
174 final long nn = f.length();
175 out.println(
" f.length = " + nn);
181 }
catch (FileNotFoundException ex) {
183 +
" does not exist, is a directory, or"
184 +
" cannot be opened for reading.");
185 throw new ClassNotFoundException(msg, ex);
189 final FileChannel fc = fis.getChannel();
191 out.println(
" fc = " + fc);
205 }
catch (IOException ex) {
206 final String msg = (
"cannot get size of file " + f);
207 throw new ClassNotFoundException(msg, ex);
212 if (n > Integer.MAX_VALUE) {
214 +
" larger than Integer.MAX_VALUE.");
215 throw new ClassFormatError(msg);
217 bb = ByteBuffer.allocateDirect((
int)n);
222 while ((k = fc.read(bb)) > 0) {
223 out.println(
" read " + k +
" bytes");
225 }
catch (IOException ex) {
226 final String msg = (
"cannot read file " + f);
227 throw new ClassNotFoundException(msg, ex);
229 assert (bb.remaining() == 0);
234 }
catch (IOException ex) {
235 final String msg = (
"cannot close FileChannel " + fc);
236 throw new ClassNotFoundException(msg, ex);
240 }
catch (IOException ex) {
241 final String msg = (
"cannot close FileInputStream " + fis);
242 throw new ClassNotFoundException(msg, ex);
246 out.println(
"<-- SelfishFileClassLoader.getClassData(String)");
257 protected Class<?> loadClass(
String name,
boolean resolve)
258 throws ClassNotFoundException {
259 out.println(
"--> SelfishFileClassLoader.loadClass(String, boolean)");
262 Class<?> cls = findLoadedClass(name);
264 out.println(
" already loaded " + cls);
272 if (name.startsWith(
"test")
273 || name.startsWith(
"myjapi")
274 || name.startsWith(
"jtie")) {
275 out.println(
" self: loading " + name +
" ...");
276 final ByteBuffer bb = getClassData(name);
277 cls = defineClass(name, bb, null);
279 out.println(
" parent: loading " + name +
" ...");
280 cls = getParent().loadClass(name);
282 assert (cls != null);
284 out.println(
" ... loaded " + cls
285 +
" <" + cls.getClassLoader() +
">");
289 out.println(
" linking " + cls +
" ...");
291 out.println(
" ... linked " + cls);
294 out.println(
"<-- SelfishFileClassLoader.loadClass(String, boolean)");
303 static class FilterClassLoader
extends ClassLoader {
306 protected final String[] prefixes;
308 public FilterClassLoader(
String[] prefixes) {
309 out.println(
"--> FilterClassLoader()");
310 out.println(
" this = " +
this);
311 out.println(
" getParent() = " + getParent());
312 out.println(
" prefixes[] = {");
313 for (
int i = 0;
i < prefixes.length;
i++) {
314 out.println(
" \"" + prefixes[
i] +
"\"");
317 this.prefixes = prefixes;
318 out.println(
"<-- FilterClassLoader()");
322 protected Class<?> findClass(
String name)
323 throws ClassNotFoundException {
324 assert (
false) :
"should never be called";
325 throw new ClassNotFoundException();
329 protected Class<?> loadClass(
String name,
boolean resolve)
330 throws ClassNotFoundException {
331 out.println(
"--> FilterClassLoader.loadClass(String, boolean)");
335 assert (findLoadedClass(name) == null);
338 for (
int i = prefixes.length - 1;
i >= 0;
i--) {
339 if (name.startsWith(prefixes[
i])) {
340 out.println(
" redirect loading " + name);
341 out.println(
"<<< FilterClassLoader.loadClass(String, boolean)");
342 throw new ClassNotFoundException();
347 out.println(
" delegate loading " + name);
348 cls = getParent().loadClass(name);
349 assert (cls != null);
355 out.println(
" linking " + cls +
" ...");
357 out.println(
" ... linked " + cls);
360 out.println(
"<-- FilterClassLoader.loadClass(String, boolean)");
368 static class MyURLClassLoader
extends URLClassLoader {
370 public MyURLClassLoader(URL[] urls, ClassLoader parent) {
372 out.println(
"--> MyURLClassLoader(URL[], ClassLoader)");
373 out.println(
" this = " +
this);
374 out.println(
" getParent() = " + getParent());
375 out.println(
" urls[] = {");
376 for (
int i = 0; i < urls.length; i++) {
377 out.println(
" " + urls[i]);
380 out.println(
"<-- MyURLClassLoader(URL[], ClassLoader)");
383 protected Class<?> findClass(
String name)
384 throws ClassNotFoundException {
385 out.println(
"--> MyURLClassFinder.findClass(String, boolean)");
386 out.println(
" finding " + name +
" ...");
387 Class<?> cls = super.findClass(name);
388 out.println(
" ... found " + cls
389 +
" <" + cls.getClassLoader() +
">");
390 out.println(
"<-- MyURLClassFinder.findClass(String, boolean)");
394 protected Class<?> loadClass(
String name,
boolean resolve)
395 throws ClassNotFoundException {
396 out.println(
"--> MyURLClassLoader.loadClass(String, boolean)");
397 out.println(
" loading " + name +
" ...");
398 Class<?> cls = super.loadClass(name, resolve);
399 out.println(
" ... loaded " + cls
400 +
" <" + cls.getClassLoader() +
">");
401 out.println(
"<-- MyURLClassLoader.loadClass(String, boolean)");
409 static private URL[] classPathURLs() throws MalformedURLException {
410 final String cp = System.getProperty(
"java.class.path");
411 assert (cp != null) : (
"classpath = '" + cp +
"'");
412 final String[] s = cp.split(File.pathSeparator);
413 final URL[] urls =
new URL[s.length];
414 for (
int i = 0; i < s.length; i++) {
415 urls[
i] =
new File(s[i]).toURI().toURL();
420 static public void test0()
421 throws ClassNotFoundException, NoSuchMethodException,
422 IllegalAccessException, InvocationTargetException,
423 MalformedURLException, InstantiationException {
425 out.println(
"--> MyLoadUnloadTest.test0()");
428 out.println(
" MyLoadUnloadTest.class.getClassLoader() = "
429 + MyLoadUnloadTest.class.getClassLoader());
430 out.println(
" ClassLoader.getSystemClassLoader() = "
431 + ClassLoader.getSystemClassLoader());
434 final String pprefixes = System.getProperty(pprefixes_prop,
436 final String[] pprefix = pprefixes.split(
",");
437 final String cname = System.getProperty(cname_prop,
"test.MyJapiTest");
438 final String mname = System.getProperty(mname_prop,
"test");
440 out.println(
" using properties");
441 out.println(
" pprefixes = '" + pprefixes +
"'");
442 out.println(
" cname = '" + cname +
"'");
443 out.println(
" mname = '" + mname +
"'");
447 out.println(
" create FilterClassLoader ...");
448 final ClassLoader fcl =
new FilterClassLoader(pprefix);
449 out.println(
" ... created " + fcl);
452 out.println(
" create URLClassLoader ...");
453 final URL[] urls = classPathURLs();
455 final ClassLoader ucl =
new URLClassLoader(urls, fcl);
456 out.println(
" ... created " + ucl);
459 cl =
new WeakReference<ClassLoader>(ucl);
463 out.println(
" load class ...");
464 Class cls = ucl.loadClass(cname);
465 out.println(
" ... loaded " + cls
466 +
" <" + cls.getClassLoader() +
">");
469 out.println(
" get method: " + mname +
" ...");
470 Method m = cls.getMethod(
"test");
471 out.println(
" ... got method: " + m);
474 out.println(
" create instance: ...");
475 Object o = cls.newInstance();
476 out.println(
" ... created instance: " + o);
479 out.println(
" invoke method: " + m +
" ...");
481 out.println(
" ... invoked method: " + m);
484 out.println(
"<-- MyLoadUnloadTest.test0()");
491 static private void gc() {
492 out.println(
"--> MyLoadUnloadTest.gc()");
493 out.println(
" jvm mem: " + (rt.totalMemory() - rt.freeMemory())/1024
494 +
" KiB [" + rt.totalMemory()/1024 +
" KiB]");
497 final int nFullGCs = 100;
499 for (
int i = 0; i < nFullGCs; i++) {
501 long newfree = rt.freeMemory();
504 synchronized (MyLoadUnloadTest.class) {
506 out.println(
" rt.gc()");
510 rt.runFinalization();
512 newfree = rt.freeMemory();
514 }
while (newfree > oldfree);
516 out.println(
" jvm mem: " + (rt.totalMemory() - rt.freeMemory())/1024
517 +
" KiB [" + rt.totalMemory()/1024 +
" KiB]");
518 out.println(
"<-- MyLoadUnloadTest.gc()");
521 static public void test()
522 throws ClassNotFoundException, NoSuchMethodException,
523 IllegalAccessException, InvocationTargetException,
524 MalformedURLException, InstantiationException {
526 out.println(
"--> MyLoadUnloadTest.test()");
528 for (
int i = 0; i < 3; i++) {
540 if (
cl.get() != null) {
541 out.println(
"!!! the class loader with the native library"
542 +
" has not been garbage collected (for instance,"
543 +
" due to a strong caching reference)!");
549 out.println(
"<-- MyLoadUnloadTest.test()");
553 static public void main(
String[] args)
555 out.println(
"--> MyLoadUnloadTest.main()");
560 synchronized (MyLoadUnloadTest.class) {
571 out.println(
"<-- MyLoadUnloadTest.main()");