1 /*
2  * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  *
26  */
27 
28 import java.lang.reflect.Method;
29 import java.net.MalformedURLException;
30 import java.net.URL;
31 import java.net.URLClassLoader;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36 
37 import java.rmi.server.RMIClassLoader;
38 import java.rmi.server.RMIClassLoaderSpi;
39 
40 public class TestProvider extends RMIClassLoaderSpi {
41 
42     public static final Method loadClassMethod;
43     public static final Method loadProxyClassMethod;
44     public static final Method getClassLoaderMethod;
45     public static final Method getClassAnnotationMethod;
46     static {
47         try {
48             loadClassMethod = RMIClassLoaderSpi.class.getMethod(
49                 "loadClass", new Class[] {
50                     String.class, String.class, ClassLoader.class
51                 });
52             loadProxyClassMethod = RMIClassLoaderSpi.class.getMethod(
53                 "loadProxyClass", new Class[] {
54                     String.class, String[].class, ClassLoader.class
55                 });
56             getClassLoaderMethod = RMIClassLoaderSpi.class.getMethod(
57                 "getClassLoader", new Class[] { String.class });
58             getClassAnnotationMethod = RMIClassLoaderSpi.class.getMethod(
59                 "getClassAnnotation", new Class[] { Class.class });
60         } catch (NoSuchMethodException e) {
61             Error error = new NoSuchMethodError();
62             error.initCause(e);
63             throw error;
64         }
65     }
66 
67     public static final Class loadClassReturn =
68         (new Object() { }).getClass();
69     public static final Class loadProxyClassReturn =
70         (new Object() { }).getClass();
71     public static final ClassLoader getClassLoaderReturn =
72         URLClassLoader.newInstance(new URL[0]);
73     public static final String getClassAnnotationReturn = new String();
74 
75     public static List invocations =
76         Collections.synchronizedList(new ArrayList(1));
77 
TestProvider()78     public TestProvider() {
79         System.err.println("TestProvider()");
80     }
81 
loadClass(String codebase, String name, ClassLoader defaultLoader)82     public Class loadClass(String codebase, String name,
83                            ClassLoader defaultLoader)
84         throws MalformedURLException, ClassNotFoundException
85     {
86         invocations.add(new Invocation(loadClassMethod,
87             new Object[] { codebase, name, defaultLoader }));
88 
89         return loadClassReturn;
90     }
91 
loadProxyClass(String codebase, String[] interfaces, ClassLoader defaultLoader)92     public Class loadProxyClass(String codebase, String[] interfaces,
93                                 ClassLoader defaultLoader)
94         throws MalformedURLException, ClassNotFoundException
95     {
96         invocations.add(new Invocation(loadProxyClassMethod,
97             new Object[] { codebase, interfaces, defaultLoader }));
98 
99         return loadProxyClassReturn;
100     }
101 
getClassLoader(String codebase)102     public ClassLoader getClassLoader(String codebase)
103         throws MalformedURLException
104     {
105         invocations.add(new Invocation(
106             getClassLoaderMethod, new Object[] { codebase }));
107 
108         return getClassLoaderReturn;
109     }
110 
getClassAnnotation(Class<?> cl)111     public String getClassAnnotation(Class<?> cl) {
112         invocations.add(new Invocation(
113             getClassAnnotationMethod, new Object[] { cl }));
114 
115         return getClassAnnotationReturn;
116     }
117 
118     public static class Invocation {
119         public Method method;
120         public Object[] args;
121 
Invocation(Method method, Object[] args)122         public Invocation(Method method, Object[] args) {
123             this.method = method;
124             this.args = (Object[]) args.clone();
125         }
126     }
127 
exerciseTestProvider(Object loadClassReturn, Object loadProxyClassReturn, Object getClassLoaderReturn, Object getClassAnnotationReturn, List invocationQueue)128     public static void exerciseTestProvider(Object loadClassReturn,
129                                             Object loadProxyClassReturn,
130                                             Object getClassLoaderReturn,
131                                             Object getClassAnnotationReturn,
132                                             List invocationQueue)
133         throws MalformedURLException, ClassNotFoundException
134     {
135         URL codebaseURL = new URL("http://the-black-lodge/dale-cooper/");
136         String codebase = codebaseURL.toString();
137         String classname = "Foo";
138         ClassLoader defaultLoader = URLClassLoader.newInstance(new URL[0]);
139         String[] interfaces = new String[] { "Bar", "Baz" };
140         Class dummyClass = (new Object() { }).getClass();
141 
142         TestLibrary.suggestSecurityManager(null);
143 
144         String testcase;
145         Object ret;
146 
147         /*
148          *
149          */
150         testcase = "RMIClassLoader.loadClass(String)";
151         System.err.println("testing " + testcase);
152 
153         ret = RMIClassLoader.loadClass(classname);
154         if (ret != loadClassReturn) {
155              throw new RuntimeException("TEST FAILED: " +
156                 testcase + " returned " + ret);
157         }
158         verifyOneInvocation(TestProvider.loadClassMethod,
159             new Object[] { null, classname, null }, invocationQueue);
160 
161         /*
162          *
163          */
164         testcase = "RMIClassLoader.loadClass(URL,String)";
165         System.err.println("testing " + testcase);
166 
167         ret = RMIClassLoader.loadClass(codebaseURL, classname);
168         if (ret != loadClassReturn) {
169              throw new RuntimeException("TEST FAILED: " +
170                 testcase + " returned " + ret);
171         }
172         verifyOneInvocation(TestProvider.loadClassMethod,
173             new Object[] { codebase, classname, null }, invocationQueue);
174 
175         /*
176          *
177          */
178         testcase = "RMIClassLoader.loadClass(String,String)";
179         System.err.println("testing " + testcase);
180 
181         ret = RMIClassLoader.loadClass(codebase, classname);
182         if (ret != loadClassReturn) {
183              throw new RuntimeException("TEST FAILED: " +
184                 testcase + " returned " + ret);
185         }
186         verifyOneInvocation(TestProvider.loadClassMethod,
187             new Object[] { codebase, classname, null }, invocationQueue);
188 
189         /*
190          *
191          */
192         testcase = "RMIClassLoader.loadClass(String,String,ClassLoader";
193         System.err.println("testing " + testcase);
194 
195         ret = RMIClassLoader.loadClass(codebase, classname, defaultLoader);
196         if (ret != loadClassReturn) {
197              throw new RuntimeException("TEST FAILED: " +
198                 testcase + " returned " + ret);
199         }
200         verifyOneInvocation(TestProvider.loadClassMethod,
201             new Object[] { codebase, classname, defaultLoader },
202             invocationQueue);
203 
204         /*
205          *
206          */
207         testcase =
208             "RMIClassLoader.loadProxyClass(String,String[],ClassLoader)";
209         System.err.println("testing " + testcase);
210 
211         ret = RMIClassLoader.loadProxyClass(codebase, interfaces,
212                                             defaultLoader);
213         if (ret != loadProxyClassReturn) {
214             throw new RuntimeException("TEST FAILED: " +
215                 testcase + " returned " + ret);
216         }
217         verifyOneInvocation(TestProvider.loadProxyClassMethod,
218             new Object[] { codebase, interfaces, defaultLoader },
219             invocationQueue);
220 
221         /*
222          *
223          */
224         testcase = "RMIClassLoader.getClassLoader(String)";
225         System.err.println("testing " + testcase);
226 
227         ret = RMIClassLoader.getClassLoader(codebase);
228         if (ret != getClassLoaderReturn) {
229             throw new RuntimeException("TEST FAILED: " +
230                 testcase + " returned " + ret);
231         }
232         verifyOneInvocation(TestProvider.getClassLoaderMethod,
233             new Object[] { codebase }, invocationQueue);
234 
235         /*
236          *
237          */
238         testcase = "RMIClassLoader.getClassAnnotation(Class)";
239         System.err.println("testing " + testcase);
240 
241         ret = RMIClassLoader.getClassAnnotation(dummyClass);
242         if (ret != getClassAnnotationReturn) {
243             throw new RuntimeException("TEST FAILED: " +
244                 testcase + " returned " + ret);
245         }
246         verifyOneInvocation(TestProvider.getClassAnnotationMethod,
247             new Object[] { dummyClass }, invocationQueue);
248 
249         System.err.println("TEST PASSED");
250     }
251 
verifyOneInvocation(Method method, Object[] args, List invocationQueue)252     private static void verifyOneInvocation(Method method, Object[] args,
253                                             List invocationQueue)
254     {
255         TestProvider.Invocation inv =
256             (TestProvider.Invocation) invocationQueue.remove(0);
257 
258         if (!method.equals(inv.method)) {
259             throw new RuntimeException(
260                 "unexpected provider method invoked: expected " + method +
261                 ", detected " + inv.method);
262         }
263 
264         List expectedArgs = Arrays.asList(args);
265         List detectedArgs = Arrays.asList(inv.args);
266         if (!expectedArgs.equals(detectedArgs)) {
267             throw new RuntimeException("TEST FAILED: " +
268                 "unexpected provider method invocation arguments: " +
269                 "expected " + expectedArgs + ", detected " + detectedArgs);
270         }
271 
272         if (!invocationQueue.isEmpty()) {
273             inv = (TestProvider.Invocation)
274                 invocationQueue.remove(0);
275             throw new RuntimeException("TEST FAILED: " +
276                 "unexpected provider invocation: " + inv.method + " " +
277                 Arrays.asList(inv.args));
278         }
279     }
280 }
281