Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: f921acce77aa6913eba09ac68befd6ed9c4bfdcd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*******************************************************************************
 * Copyright (c) 2005, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.hookregistry;

import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.loader.ModuleClassLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;

/**
 * A class loading hook that hooks into a module class loader
 */
public abstract class ClassLoaderHook {
	/**
	 * Gets called by a classpath manager before defining a class.  This method allows a class loading hook 
	 * to process the bytes of a class that is about to be defined and return a transformed byte array.
	 * @param name the name of the class being defined
	 * @param classbytes the bytes of the class being defined
	 * @param classpathEntry the ClasspathEntry where the class bytes have been read from.
	 * @param entry the BundleEntry source of the class bytes
	 * @param manager the class path manager used to define the requested class
	 * @return a transformed array of classbytes or null if the original bytes should be used.
	 */
	public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
		return null;
	}

	/**
	 * Gets called by a classpath manager before defining a class.  This method allows a class loading hook
	 * to reject a transformation to the class bytes by a 
	 * {@link #processClass(String, byte[], ClasspathEntry, BundleEntry, ClasspathManager) processClass} method.
	 * @param name the name of the class being defined
	 * @param transformedBytes the transformed bytes of the class being defined
	 * @param classpathEntry the ClasspathEntry where the class bytes have been read from
	 * @param entry the BundleEntry source of the class bytes
	 * @param manager the class path manager used to define the requested class
	 * @return returns true if the modified bytes should be rejected; otherwise false is returned
	 */
	public boolean rejectTransformation(String name, byte[] transformedBytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
		return false;
	}

	/**
	 * Gets called by a classpath manager when looking for ClasspathEntry objects.  This method allows 
	 * a classloading hook to add additional ClasspathEntry objects
	 * @param cpEntries the list of ClasspathEntry objects currently available for the requested classpath
	 * @param cp the name of the requested classpath
	 * @param hostmanager the classpath manager the requested ClasspathEntry is for
	 * @param sourceGeneration the source generation of the requested ClasspathEntry
	 * @return true if a ClasspathEntry has been added to cpEntries
	 */
	public boolean addClassPathEntry(ArrayList<ClasspathEntry> cpEntries, String cp, ClasspathManager hostmanager, Generation sourceGeneration) {
		return false;
	}

	/**
	 * Gets called by a base data during {@link ModuleClassLoader#findLibrary(String)}.
	 * A this method is called for each configured class loading hook until one 
	 * class loading hook returns a non-null value.  If no class loading hook returns 
	 * a non-null value then the default behavior will be used.
	 * @param generation the bundle generation to find a native library for.
	 * @param libName the name of the native library.
	 * @return The absolute path name of the native library or null.
	 */
	public String findLocalLibrary(Generation generation, String libName) {
		return null;
	}

	/**
	 * Gets called by a bundle loader when {@link BundleLoader#getClassLoader()}
	 * is called the first time in order to allow a hook to create the class loader.
	 * This should rarely, if ever be overridden.  The default implementation
	 * returns null indicating the built-in implementation should be used.
	 * Only one hook is able to provide the implementation of the module class loader
	 * and the first one to return non-null wins.
	 * 
	 * @param parent the parent classloader
	 * @param configuration the equinox configuration
	 * @param delegate the delegate for this classloader
	 * @param generation the generation for this class loader
	 * @return returns an implementation of a module class loader or <code>null</code>
	 * if the built-in implemention is to be used.
	 */
	public ModuleClassLoader createClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, Generation generation) {
		// do nothing
		return null;
	}

	/**
	 * Gets called by a classpath manager at the end of 
	 * {@link BundleLoader#getClassLoader()} is called the first time and a class loader is created.
	 * @param classLoader the newly created bundle classloader
	 */
	public void classLoaderCreated(ModuleClassLoader classLoader) {
		// do nothing
	}

	/**
	 * Called by a {@link BundleLoader#findClass(String)} method before delegating to the resolved constraints and 
	 * local bundle for a class load.  If this method returns null then normal delegation is done.  If this method 
	 * returns a non-null value then the rest of the delegation process is skipped and the returned value is used.
	 * If this method throws a <code>ClassNotFoundException</code> then the calling 
	 * {@link BundleLoader#findClass(String)} method re-throws the exception.
	 * @param name the name of the class to find
	 * @param classLoader the module class loader
	 * @return the class found by this hook or null if normal delegation should continue
	 * @throws ClassNotFoundException to terminate the delegation and throw an exception
	 */
	public Class<?> preFindClass(String name, ModuleClassLoader classLoader) throws ClassNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link BundleLoader#findClass(String)} method after delegating to the resolved constraints and 
	 * local bundle for a class load.  This method will only be called if no class was found
	 * from the normal delegation.
	 * @param name the name of the class to find
	 * @param classLoader the bundle class loader
	 * @return the class found by this hook or null if normal delegation should continue
	 * @throws ClassNotFoundException to terminate the delegation and throw an exception
	 */
	public Class<?> postFindClass(String name, ModuleClassLoader classLoader) throws ClassNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link BundleLoader#findResource(String)} before delegating to the resolved constraints and 
	 * local bundle for a resource load.  If this method returns null then normal delegation is done.  
	 * If this method returns a non-null value then the rest of the delegation process is skipped and the returned value is used.
	 * If this method throws an <code>FileNotFoundException</code> then the delegation is terminated.
	 * @param name the name of the resource to find
	 * @param classLoader the bundle class loader
	 * @return the resource found by this hook or null if normal delegation should continue
	 * @throws FileNotFoundException to terminate the delegation
	 */
	public URL preFindResource(String name, ModuleClassLoader classLoader) throws FileNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link BundleLoader#findResource(String)} after delegating to the resolved constraints and 
	 * local bundle for a resource load.  This method will only be called if no resource was found
	 * from the normal delegation.
	 * @param name the name of the resource to find
	 * @param classLoader the bundle class loader
	 * @return the resource found by this hook or null if normal delegation should continue
	 * @throws FileNotFoundException to terminate the delegation
	 */
	public URL postFindResource(String name, ModuleClassLoader classLoader) throws FileNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link BundleLoader#findResources(String)} before delegating to the resolved constraints and 
	 * local bundle for a resource load.  If this method returns null then normal delegation is done.  
	 * If this method returns  a non-null value then the rest of the delegation process is skipped and the returned value is used.
	 * If this method throws an <code>FileNotFoundException</code> then the delegation is terminated
	 * @param name the name of the resource to find
	 * @param classLoader the bundle class loader
	 * @return the resources found by this hook or null if normal delegation should continue
	 * @throws FileNotFoundException to terminate the delegation
	 */
	public Enumeration<URL> preFindResources(String name, ModuleClassLoader classLoader) throws FileNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link BundleLoader#findResources(String)} after delegating to the resolved constraints and 
	 * local bundle for a resource load.  This method will only be called if no resources were found
	 * from the normal delegation.
	 * @param name the name of the resource to find
	 * @param classLoader the bundle class loader
	 * @return the resources found by this hook or null if normal delegation should continue
	 * @throws FileNotFoundException to terminate the delegation
	 */
	public Enumeration<URL> postFindResources(String name, ModuleClassLoader classLoader) throws FileNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link ClasspathManager} before normal delegation.  If this method returns 
	 * a non-null value then the rest of the delegation process is skipped and the returned value
	 * is used.
	 * @param name the name of the library to find
	 * @param classLoader the bundle class loader
	 * @return the library found by this hook or null if normal delegation should continue
	 * @throws FileNotFoundException to terminate the delegation
	 */
	public String preFindLibrary(String name, ModuleClassLoader classLoader) throws FileNotFoundException {
		return null;
	}

	/**
	 * Called by a {@link ClasspathManager} after normal delegation.  This method will only be called
	 * if no library was found from the normal delegation.
	 * @param name the name of the library to find
	 * @param classLoader the bundle class loader
	 * @return the library found by this hook or null if normal delegation should continue
	 */
	public String postFindLibrary(String name, ModuleClassLoader classLoader) {
		return null;
	}

	/**
	 * Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} before 
	 * searching the local classloader for a class.  A classpath manager will call this method for 
	 * each configured class loading stat hook.
	 * @param name the name of the requested class
	 * @param manager the classpath manager used to find and load the requested class
	 * @throws ClassNotFoundException to prevent the requested class from loading
	 */
	public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
		// do nothing
	}

	/**
	 * Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} after
	 * searching the local classloader for a class. A classpath manager will call this method for 
	 * each configured class loading stat hook.
	 * @param name the name of the requested class
	 * @param clazz the loaded class or null if not found
	 * @param manager the classpath manager used to find and load the requested class
	 * @throws ClassNotFoundException 
	 */
	public void postFindLocalClass(String name, Class<?> clazz, ClasspathManager manager) throws ClassNotFoundException {
		// do nothing
	}

	/**
	 * Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} before
	 * searching the local classloader for a resource. A classpath manager will call this method for 
	 * each configured class loading stat hook.
	 * @param name the name of the requested resource
	 * @param manager the classpath manager used to find the requested resource
	 */
	public void preFindLocalResource(String name, ClasspathManager manager) {
		// do nothing
	}

	/**
	 * Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} after
	 * searching the local classloader for a resource. A classpath manager will call this method for 
	 * each configured class loading stat hook.
	 * @param name the name of the requested resource
	 * @param resource the URL to the requested resource or null if not found
	 * @param manager the classpath manager used to find the requested resource
	 */
	public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
		// do nothing
	}

	/**
	 * Gets called by a classpath manager after an attempt is made to define a class.  This method allows 
	 * a class loading stat hook to record data about a class definition. 
	 * @param name the name of the class that got defined
	 * @param clazz the class object that got defined or null if an error occurred while defining a class
	 * @param classbytes the class bytes used to define the class
	 * @param classpathEntry the ClasspathEntry where the class bytes got read from
	 * @param entry the BundleEntyr source of the class bytes
	 * @param manager the classpath manager used to define the class
	 */
	public void recordClassDefine(String name, Class<?> clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
		// do nothing
	}

	/**
	 * Returns the parent class loader to be used by all ModuleClassLoaders.
	 * A {@code null} value may be returned if this hook does not supply the parent.
	 * Only one hook is able to provide the implementation of the parent class loader
	 * and the first one to return non-null wins.
	 * @param configuration the equinox configuration
	 * @return the parent class loader to be used by all ModuleClassLoaders
	 */
	public ClassLoader getModuleClassLoaderParent(EquinoxConfiguration configuration) {
		// do nothing by default
		return null;
	}

}

Back to the top