1 /***************************************************************************************
2 * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3 * http://aspectwerkz.codehaus.org *
4 * ---------------------------------------------------------------------------------- *
5 * The software in this package is published under the terms of the LGPL license *
6 * a copy of which has been included with this distribution in the license.txt file. *
7 **************************************************************************************/
8 package test.clapp;
9
10 import java.io.File;
11 import java.net.URL;
12 import java.net.URLClassLoader;
13
14 /***
15 * App loading lots of class in lots of threads <p/>Mandatory args = thread number, loop per thread,
16 * pause between loops <br/>If no args are provided, defaults to 2, 5, 5ms. <br/><br/>Each thread
17 * loop loads DummyClass thru a dedicated URLClassLoader (no parent) at each loop
18 * <br/>test.xmldef.clapp.DummyClass and test.xmldef.clapp.ReentrantDummyClass must be in directory
19 * specified thru -DDummyClass, defaults <i>ASPECTWERKZ_HOME </i>/target/test-classes <br/>During
20 * the DummyClass clinit, another class is loaded thru another URLClassLoader (no parent)
21 *
22 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
23 */
24 public class CrazyClassLoaderApp {
25 private static final String DUMMYCLASS_LOCATION_PROP = "DummyClass";
26
27 public static String DUMMYCLASS_LOCATION = System.getProperty(DUMMYCLASS_LOCATION_PROP);
28
29 static {
30 if (DUMMYCLASS_LOCATION == null) {
31 DUMMYCLASS_LOCATION = System.getProperty("ASPECTWERKZ_HOME")
32 + File.separator
33 + "target"
34 + File.separator
35 + "test-classes";
36 }
37 }
38
39 /***
40 * log
41 */
42 private static void log(String s) {
43 System.out.println(s);
44 }
45
46 /***
47 * launch all thread and join() with them
48 */
49 public static void main(String[] args) throws Exception {
50 int thread = 2;
51 int count = 5;
52 int mspause = 5;
53 try {
54 thread = Integer.parseInt(args[0]);
55 count = Integer.parseInt(args[1]);
56 mspause = Integer.parseInt(args[2]);
57 } catch (Exception e) {
58 ;
59 }
60 long start = System.currentTimeMillis();
61 log("BEGIN:" + thread + ':' + count + ':' + mspause + ':' + DUMMYCLASS_LOCATION);
62 Thread[] threads = new Thread[thread];
63 for (int i = 0; i < thread; i++) {
64 Worker w = new Worker(count, mspause);
65 w.setPriority(Thread.MAX_PRIORITY - 1);
66 w.start();
67 log("started " + i);
68 threads[i] = w;
69 }
70 for (int i = 0; i < thread; i++) {
71 threads[i].join();
72 log("joined " + i);
73 }
74 log("END");
75 log("( " + ((int) (System.currentTimeMillis() - start) / 1000) + " s)");
76 log("classes=" + (thread * count * 2));
77 System.exit(0);
78 }
79
80 private static class Worker extends Thread {
81 public static transient int total = 0;
82
83 int count = 10;
84
85 long mspause = 1000;
86
87 URL url = null;
88
89 public Worker(int count, long mspause) {
90 this.count = count;
91 this.mspause = mspause;
92 try {
93 this.url = new java.io.File(DUMMYCLASS_LOCATION).toURL();
94 } catch (Exception e) {
95 e.printStackTrace();
96 }
97 }
98
99 public void run() {
100 int i = 0;
101 while (i < count) {
102 try {
103 i++;
104 ClassLoader tmpLoader = new URLClassLoader(new URL[] {
105 url
106 }, null);
107 Class dummyClass = tmpLoader.loadClass("test.clapp.DummyClass");
108 Object dummyInstance = dummyClass.newInstance();
109 total++;
110 log(total
111 + " "
112 + this.getName()
113 + ':'
114 + i
115 + ":DumyClass.hashcode="
116 + dummyInstance.getClass().hashCode());
117 synchronized (this) {
118 wait(mspause);
119 }
120 } catch (Exception e) {
121 e.printStackTrace();
122 }
123 }
124 }
125 }
126 }