Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/ClassLoader.java
12513 views
1
/*[INCLUDE-IF Sidecar18-SE]*/
2
/*******************************************************************************
3
* Copyright (c) 1998, 2022 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
22
*******************************************************************************/
23
package java.lang;
24
25
import java.io.*;
26
import java.security.CodeSource;
27
import java.security.ProtectionDomain;
28
29
/*[IF !Sidecar19-SE]
30
import com.ibm.oti.vm.AbstractClassLoader;
31
/*[ENDIF]*/
32
import com.ibm.oti.vm.VM;
33
34
import java.net.URL;
35
import java.util.Enumeration;
36
import java.util.HashMap;
37
import java.util.Hashtable;
38
import java.util.LinkedList;
39
import java.util.Map;
40
import java.util.NoSuchElementException;
41
import java.util.Queue;
42
import java.util.Vector;
43
import java.util.Collections;
44
import java.util.WeakHashMap;
45
import java.lang.ref.ReferenceQueue;
46
import java.lang.ref.WeakReference;
47
import java.lang.reflect.*;
48
import java.security.cert.Certificate;
49
import sun.security.util.SecurityConstants;
50
51
/*[IF JAVA_SPEC_VERSION >= 11]*/
52
import java.lang.reflect.Modifier;
53
import java.util.Spliterator;
54
import java.util.Spliterators;
55
import java.util.stream.Stream;
56
import java.util.stream.StreamSupport;
57
import jdk.internal.module.ServicesCatalog;
58
import java.util.concurrent.ConcurrentHashMap;
59
import jdk.internal.reflect.CallerSensitive;
60
import jdk.internal.loader.ClassLoaders;
61
import jdk.internal.loader.BootLoader;
62
/*[ELSE]
63
import sun.reflect.CallerSensitive;
64
/*[ENDIF]*/
65
66
/*[IF JAVA_SPEC_VERSION >= 15]*/
67
import jdk.internal.loader.NativeLibraries;
68
import jdk.internal.loader.NativeLibrary;
69
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
70
71
/*[IF JAVA_SPEC_VERSION >= 18]*/
72
import jdk.internal.reflect.CallerSensitiveAdapter;
73
/*[ENDIF] JAVA_SPEC_VERSION >= 18 */
74
75
/**
76
* ClassLoaders are used to dynamically load, link and install
77
* classes into a running image.
78
*
79
* @version initial
80
*/
81
public abstract class ClassLoader {
82
private static CodeSource defaultCodeSource = new CodeSource(null, (Certificate[])null);
83
84
85
/**
86
* This is the bootstrap ClassLoader
87
*/
88
static ClassLoader bootstrapClassLoader;
89
/*[IF Sidecar19-SE]*/
90
private ServicesCatalog servicesCatalog;
91
private final Module unnamedModule;
92
private final String classLoaderName;
93
private final static String DELEGATING_CL = "jdk.internal.reflect.DelegatingClassLoader"; //$NON-NLS-1$
94
/*[ELSE]
95
private final static String DELEGATING_CL = "sun.reflect.DelegatingClassLoader"; //$NON-NLS-1$
96
/*[ENDIF]*/
97
private boolean isDelegatingCL = false;
98
99
/*
100
* This is the application ClassLoader
101
*/
102
private static ClassLoader applicationClassLoader;
103
private static boolean initSystemClassLoader;
104
private final static boolean isAssertOptionFound = foundJavaAssertOption();
105
106
private long vmRef;
107
ClassLoader parent;
108
109
/*[PR CMVC 130382] Optimize checking ClassLoader assertion status */
110
private static boolean checkAssertionOptions;
111
/*[PR CMVC 94437] fix deadlocks */
112
/*[PR 122459] LIR646 - Remove use of generic object for synchronization */
113
private static final class AssertionLock { AssertionLock() {} }
114
private final Object assertionLock = new AssertionLock();
115
private boolean defaultAssertionStatus;
116
private Map<String, Boolean> packageAssertionStatus;
117
private Map<String, Boolean> classAssertionStatus;
118
/*[IF Sidecar19-SE]*/
119
private final Hashtable<String, NamedPackage> packages = new Hashtable<>();
120
private volatile ConcurrentHashMap<?, ?> classLoaderValueMap;
121
/*[ELSE]
122
private final Hashtable<String, Package> packages = new Hashtable<>();
123
/*[ENDIF] Sidecar19-SE*/
124
/*[PR CMVC 94437] fix deadlocks */
125
/*[PR 122459] LIR646 - Remove use of generic object for synchronization */
126
private static final class LazyInitLock { LazyInitLock() {} }
127
private final Object lazyInitLock = new LazyInitLock();
128
private volatile Hashtable<Class<?>, Object[]> classSigners; // initialized if needed
129
private volatile Hashtable<String, Certificate[]> packageSigners;
130
private static Certificate[] emptyCertificates = new Certificate[0];
131
private volatile ProtectionDomain defaultProtectionDomain;
132
133
// store parallel capable classloader classes
134
private static Map<Class<?>, Object> parallelCapableCollection;
135
// store class binary name based lock
136
private volatile Hashtable<String, ClassNameLockRef> classNameBasedLock;
137
// for performance purpose, only check once if registered as parallel capable
138
// assume customer classloader follow Java specification requirement
139
// in which registerAsParallelCapable shall be invoked during initialization
140
private boolean isParallelCapable;
141
private static final class ClassNameBasedLock { ClassNameBasedLock() {} }
142
private static final Package[] EMPTY_PACKAGE_ARRAY = new Package[0];
143
144
// Cache instances of java.lang.invoke.MethodType generated from method descriptor strings
145
private Map<String, java.lang.invoke.MethodType> methodTypeFromMethodDescriptorStringCache;
146
147
private static boolean allowArraySyntax;
148
/*[IF Sidecar19-SE]*/
149
private static boolean lazyClassLoaderInit = true;
150
/*[ELSE]
151
private static boolean lazyClassLoaderInit = false;
152
/*[ENDIF]*/
153
private static boolean specialLoaderInited = false;
154
private static InternalAnonymousClassLoader internalAnonClassLoader;
155
/*[IF JAVA_SPEC_VERSION >= 15]*/
156
private NativeLibraries nativelibs = null;
157
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
158
private static native void initAnonClassLoader(InternalAnonymousClassLoader anonClassLoader);
159
160
/*[PR JAZZ 73143]: ClassLoader incorrectly discards class loading locks*/
161
static final class ClassNameLockRef extends WeakReference<Object> implements Runnable {
162
private static final ReferenceQueue<Object> queue = new ReferenceQueue<>();
163
private final String key;
164
private final Hashtable<?, ?> classNameLockHT;
165
public ClassNameLockRef(Object referent, String keyValue, Hashtable<?, ?> classNameLockHTValue) {
166
super(referent, queue);
167
key = keyValue;
168
classNameLockHT = classNameLockHTValue;
169
}
170
@Override
171
public void run() {
172
synchronized(classNameLockHT) {
173
if (classNameLockHT.get(key) == this) {
174
classNameLockHT.remove(key);
175
}
176
}
177
}
178
}
179
180
static final void initializeClassLoaders() {
181
if (null != bootstrapClassLoader) {
182
return;
183
}
184
parallelCapableCollection = Collections.synchronizedMap(new WeakHashMap<>());
185
186
allowArraySyntax = "true".equalsIgnoreCase( //$NON-NLS-1$
187
System.internalGetProperties().getProperty("sun.lang.ClassLoader.allowArraySyntax")); //$NON-NLS-1$
188
189
/*[PR CMVC 193184] reflect.cache must be enabled here, otherwise performance slow down is experienced */
190
String propValue = System.internalGetProperties().getProperty("reflect.cache"); //$NON-NLS-1$
191
if (propValue != null) propValue = propValue.toLowerCase();
192
/* Do not enable reflect cache if -Dreflect.cache=false is in commandline */
193
boolean reflectCacheEnabled = false;
194
boolean reflectCacheDebug = false;
195
if (!"false".equals(propValue)) { //$NON-NLS-1$
196
/*JAZZ 42080: Turning off reflection caching for cloud to reduce Object Leaks*/
197
reflectCacheEnabled = true;
198
if (propValue != null) {
199
int debugIndex = propValue.indexOf("debug"); //$NON-NLS-1$
200
if (debugIndex >= 0) {
201
/*[PR 125873] Improve reflection cache */
202
/* reflect.cache=boot is handled in completeInitialization() */
203
reflectCacheDebug = true;
204
}
205
}
206
}
207
208
try {
209
/* CMVC 179008 - b143 needs ProtectionDomain initialized here */
210
Class.forName("java.security.ProtectionDomain"); //$NON-NLS-1$
211
} catch(ClassNotFoundException e) {
212
// ignore
213
}
214
215
/*[IF JAVA_SPEC_VERSION >= 11]*/
216
// This static method call ensures jdk.internal.loader.ClassLoaders.BOOT_LOADER initialization first
217
jdk.internal.loader.ClassLoaders.platformClassLoader();
218
if (bootstrapClassLoader.servicesCatalog != null) {
219
throw new InternalError("bootstrapClassLoader.servicesCatalog is NOT null "); //$NON-NLS-1$
220
}
221
bootstrapClassLoader.servicesCatalog = BootLoader.getServicesCatalog();
222
if (bootstrapClassLoader.classLoaderValueMap != null) {
223
/*[IF JAVA_SPEC_VERSION < 17]*/
224
throw new InternalError("bootstrapClassLoader.classLoaderValueMap is NOT null "); //$NON-NLS-1$
225
/*[ENDIF] JAVA_SPEC_VERSION < 17 */
226
} else {
227
bootstrapClassLoader.classLoaderValueMap = BootLoader.getClassLoaderValueMap();
228
}
229
applicationClassLoader = ClassLoaders.appClassLoader();
230
/*[ELSE] JAVA_SPEC_VERSION >= 11 */
231
ClassLoader sysTemp = null;
232
// Proper initialization requires BootstrapLoader is the first loader instantiated
233
String systemLoaderString = System.internalGetProperties().getProperty("systemClassLoader"); //$NON-NLS-1$
234
if (null == systemLoaderString) {
235
sysTemp = com.ibm.oti.vm.BootstrapClassLoader.singleton();
236
} else {
237
try {
238
sysTemp = (ClassLoader)Class.forName(systemLoaderString, true, null).newInstance();
239
} catch (Throwable x) {
240
x.printStackTrace();
241
System.exit(1);
242
}
243
}
244
bootstrapClassLoader = sysTemp;
245
AbstractClassLoader.setBootstrapClassLoader(bootstrapClassLoader);
246
lazyClassLoaderInit = true;
247
applicationClassLoader = bootstrapClassLoader;
248
/*[ENDIF] JAVA_SPEC_VERSION >= 11 */
249
250
/* [PR 78889] The creation of this classLoader requires lazy initialization. The internal classLoader struct
251
* is created in the initAnonClassLoader call. The "new InternalAnonymousClassLoader()" call must be
252
* done exactly after lazyClassLoaderInit is set and before the "java.lang.ClassLoader.lazyInitialization"
253
* is read in. This is the only way to guarantee that ClassLoader will be created with lazy initialization. */
254
internalAnonClassLoader = new InternalAnonymousClassLoader();
255
initAnonClassLoader(internalAnonClassLoader);
256
257
String lazyValue = System.internalGetProperties().getProperty("java.lang.ClassLoader.lazyInitialization"); //$NON-NLS-1$
258
if (null != lazyValue) {
259
lazyValue = lazyValue.toLowerCase();
260
if ("false".equals(lazyValue)) { //$NON-NLS-1$
261
lazyClassLoaderInit = false;
262
}
263
}
264
265
/*[IF Sidecar19-SE]*/
266
jdk.internal.misc.VM.initLevel(1);
267
/*
268
* Following code ensures that the field jdk.internal.reflect.langReflectAccess
269
* is initialized before any usage references. This is a workaround.
270
* More details are at https://github.com/eclipse-openj9/openj9/issues/3399#issuecomment-459004840.
271
*/
272
Modifier.isPublic(Modifier.PUBLIC);
273
/*[IF JAVA_SPEC_VERSION >= 10]*/
274
try {
275
/*[ENDIF] JAVA_SPEC_VERSION >= 10 */
276
System.bootLayer = jdk.internal.module.ModuleBootstrap.boot();
277
/*[IF JAVA_SPEC_VERSION >= 10]*/
278
} catch (Exception ex) {
279
System.out.println(ex);
280
Throwable t = ex.getCause();
281
while (t != null) {
282
System.out.println("Caused by: " + t); //$NON-NLS-1$
283
t = t.getCause();
284
}
285
System.exit(1);
286
}
287
/*[ENDIF] JAVA_SPEC_VERSION >= 10 */
288
jdk.internal.misc.VM.initLevel(2);
289
System.initSecurityManager(applicationClassLoader);
290
jdk.internal.misc.VM.initLevel(3);
291
/*[ELSE]*/
292
applicationClassLoader = sun.misc.Launcher.getLauncher().getClassLoader();
293
/*[ENDIF]*/
294
295
/* Find the extension class loader */
296
ClassLoader tempLoader = applicationClassLoader;
297
while (null != tempLoader.parent) {
298
tempLoader = tempLoader.parent;
299
}
300
VMAccess.setExtClassLoader(tempLoader);
301
302
/*[PR 125932] Reflect cache may be initialized by multiple Threads */
303
/*[PR JAZZ 107786] constructorParameterTypesField should be initialized regardless of reflectCacheEnabled or not */
304
Class.initCacheIds(reflectCacheEnabled, reflectCacheDebug);
305
}
306
307
/**
308
* Constructs a new instance of this class with the system
309
* class loader as its parent.
310
*
311
* @exception SecurityException
312
* if a security manager exists and it does not
313
* allow the creation of new ClassLoaders.
314
*/
315
protected ClassLoader() {
316
this(checkSecurityPermission(), null, applicationClassLoader);
317
}
318
319
/**
320
* This is a static helper method to perform security check earlier such that current ClassLoader object
321
* can't be resurrected when there is a SecurityException thrown.
322
*
323
* @return Void a unused reference passed to the Constructor
324
*/
325
private static Void checkSecurityPermission() {
326
@SuppressWarnings("removal")
327
SecurityManager security = System.getSecurityManager();
328
if (security != null) {
329
security.checkCreateClassLoader();
330
}
331
return null;
332
}
333
334
/**
335
* Constructs a new instance of this class with the given
336
* class loader as its parent.
337
*
338
* @param parentLoader ClassLoader
339
* the ClassLoader to use as the new class
340
* loaders parent.
341
* @exception SecurityException
342
* if a security manager exists and it does not
343
* allow the creation of new ClassLoaders.
344
*/
345
protected ClassLoader(ClassLoader parentLoader) {
346
this(checkSecurityPermission(), null, parentLoader);
347
}
348
349
/*[IF Sidecar19-SE]*/
350
/**
351
* Constructs a class loader with the specified name and the given
352
* class loader as its parent.
353
*
354
* @param classLoaderName name of this ClassLoader
355
* or null if not named.
356
* @param parentLoader ClassLoader
357
* the ClassLoader to use as the new class
358
* loaders parent.
359
* @exception IllegalArgumentException
360
* if the name of this class loader is empty.
361
* @exception SecurityException
362
* if a security manager exists and it does not
363
* allow the creation of new ClassLoaders.
364
*@since 9
365
*/
366
protected ClassLoader(String classLoaderName, ClassLoader parentLoader) {
367
this(checkSecurityPermission(), classLoaderName, parentLoader);
368
}
369
/*[ENDIF]*/
370
371
private ClassLoader(Void staticMethodHolder, String classLoaderName, ClassLoader parentLoader) {
372
// This assumes that DelegatingClassLoader is constructed via ClassLoader(parentLoader)
373
isDelegatingCL = DELEGATING_CL.equals(this.getClass().getName());
374
375
/*[IF JAVA_SPEC_VERSION > 8]*/
376
if ((classLoaderName != null) && classLoaderName.isEmpty()) {
377
/*[MSG "K0645", "The given class loader name can't be empty."]*/
378
throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K0645")); //$NON-NLS-1$
379
}
380
/*[ENDIF] JAVA_SPEC_VERSION > 8 */
381
382
if (parallelCapableCollection.containsKey(this.getClass())) {
383
isParallelCapable = true;
384
}
385
386
// VM Critical: must set parent before calling initializeInternal()
387
parent = parentLoader;
388
/*[IF JAVA_SPEC_VERSION == 8]*/
389
specialLoaderInited = (bootstrapClassLoader != null);
390
/*[ENDIF] JAVA_SPEC_VERSION == 8 */
391
if (specialLoaderInited) {
392
if (!lazyClassLoaderInit) {
393
VM.initializeClassLoader(this, VM.J9_CLASSLOADER_TYPE_OTHERS, isParallelCapable);
394
}
395
/*[IF JAVA_SPEC_VERSION > 8]*/
396
unnamedModule = new Module(this);
397
/*[ENDIF] JAVA_SPEC_VERSION > 8 */
398
}
399
/*[IF JAVA_SPEC_VERSION > 8]*/
400
else {
401
if (bootstrapClassLoader == null) {
402
// BootstrapClassLoader.unnamedModule is set by JVM_SetBootLoaderUnnamedModule
403
unnamedModule = null;
404
bootstrapClassLoader = this;
405
VM.initializeClassLoader(bootstrapClassLoader, VM.J9_CLASSLOADER_TYPE_BOOT, false);
406
} else {
407
// Assuming the second classloader initialized is platform classloader
408
VM.initializeClassLoader(this, VM.J9_CLASSLOADER_TYPE_PLATFORM, false);
409
specialLoaderInited = true;
410
unnamedModule = new Module(this);
411
}
412
}
413
this.classLoaderName = classLoaderName;
414
/*[ENDIF] JAVA_SPEC_VERSION > 8 */
415
416
/*[IF JAVA_SPEC_VERSION >= 19]*/
417
this.nativelibs = NativeLibraries.newInstance((this == bootstrapClassLoader) ? null : this);
418
/*[ELSEIF JAVA_SPEC_VERSION >= 17] */
419
this.nativelibs = NativeLibraries.jniNativeLibraries((this == bootstrapClassLoader) ? null : this);
420
/*[ENDIF] JAVA_SPEC_VERSION >= 19 */
421
422
if (isAssertOptionFound) {
423
initializeClassLoaderAssertStatus();
424
}
425
}
426
427
/**
428
* Constructs a new class from an array of bytes containing a
429
* class definition in class file format.
430
*
431
* @param classRep byte[]
432
* a memory image of a class file.
433
* @param offset int
434
* the offset into the classRep.
435
* @param length int
436
* the length of the class file.
437
*
438
* @return the newly defined Class
439
*
440
* @throws ClassFormatError when the bytes are invalid
441
*
442
* @deprecated Use defineClass(String, byte[], int, int)
443
*/
444
/*[IF Sidecar19-SE]*/
445
@Deprecated(forRemoval=false, since="1.1")
446
/*[ELSE]*/
447
@Deprecated
448
/*[ENDIF]*/
449
450
protected final Class<?> defineClass (byte [] classRep, int offset, int length) throws ClassFormatError {
451
return defineClass ((String) null, classRep, offset, length);
452
}
453
454
/**
455
* Constructs a new class from an array of bytes containing a
456
* class definition in class file format.
457
*
458
* @param className java.lang.String
459
* the name of the new class
460
* @param classRep byte[]
461
* a memory image of a class file
462
* @param offset int
463
* the offset into the classRep
464
* @param length int
465
* the length of the class file
466
*
467
* @return the newly defined Class
468
*
469
* @throws ClassFormatError when the bytes are invalid
470
*/
471
protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length) throws ClassFormatError {
472
return defineClass(className, classRep, offset, length, null);
473
}
474
475
private String checkClassName(String className) {
476
int index;
477
if((index = className.lastIndexOf('.')) >= 0) {
478
String packageName = className.substring(0, index);
479
/*[PR 94856]*/
480
if (className.startsWith("java.")) { //$NON-NLS-1$
481
/*[IF Sidecar19-SE]*/
482
/*[PR RTC 115588: java.* classes can be loaded by the platform class loader]*/
483
ClassLoader platformCL = ClassLoaders.platformClassLoader();
484
if (!(this == platformCL || this.isAncestorOf(platformCL))) {
485
/*[ENDIF]*/
486
/*[MSG "K01d2", "{1} - protected system package '{0}'"]*/
487
throw new SecurityException(com.ibm.oti.util.Msg.getString("K01d2", packageName, className)); //$NON-NLS-1$
488
/*[IF Sidecar19-SE]*/
489
}
490
/*[ENDIF]*/
491
}
492
return packageName;
493
}
494
return ""; //$NON-NLS-1$
495
}
496
497
/**
498
* Constructs a new class from an array of bytes containing a
499
* class definition in class file format and assigns the new
500
* class to the specified protection domain.
501
*
502
* @param className java.lang.String
503
* the name of the new class.
504
* @param classRep byte[]
505
* a memory image of a class file.
506
* @param offset int
507
* the offset into the classRep.
508
* @param length int
509
* the length of the class file.
510
* @param protectionDomain ProtectionDomain
511
* the protection domain this class should
512
* belong to.
513
*
514
* @return the newly defined Class
515
*
516
* @throws ClassFormatError when the bytes are invalid
517
*/
518
protected final Class<?> defineClass (
519
final String className,
520
final byte[] classRep,
521
final int offset,
522
final int length,
523
ProtectionDomain protectionDomain)
524
throws java.lang.ClassFormatError
525
{
526
return defineClassInternal(className, classRep, offset, length, protectionDomain, false /* allowNullProtectionDomain */);
527
}
528
529
final Class<?> defineClassInternal(
530
final String className,
531
final byte[] classRep,
532
final int offset,
533
final int length,
534
ProtectionDomain protectionDomain,
535
boolean allowNullProtectionDomain)
536
throws java.lang.ClassFormatError
537
{
538
Certificate[] certs = null;
539
if (protectionDomain != null) {
540
final CodeSource cs = protectionDomain.getCodeSource();
541
if (cs != null) certs = cs.getCertificates();
542
}
543
if (className != null) {
544
/*[PR 95417]*/
545
String packageName = checkClassName(className);
546
if ((protectionDomain == null) && allowNullProtectionDomain) {
547
/*
548
* Skip checkPackageSigners(), in this condition, the caller of this method is
549
* java.lang.Access.defineClass() and invoked by trusted system code hence
550
* there is no need to check its ProtectionDomain and associated code source certificates.
551
*/
552
} else {
553
/*[PR 93858]*/
554
checkPackageSigners(packageName, className, certs);
555
}
556
}
557
558
/*[PR 123387] bogus parameters to defineClass() should produce ArrayIndexOutOfBoundsException */
559
if (offset < 0 || length < 0 || offset > classRep.length || length > classRep.length - offset) {
560
throw new ArrayIndexOutOfBoundsException();
561
}
562
563
if ((protectionDomain == null) && !allowNullProtectionDomain) {
564
protectionDomain = getDefaultProtectionDomain();
565
}
566
567
final ProtectionDomain pd = protectionDomain;
568
/*[PR CMVC 92062] disallow extending restricted packages */
569
/*[PR CMVC 110183] checkPackageAccess() (accessClassInPackage permission) denied when granted access */
570
/*[PR CVMC 124584] checkPackageAccess(), not defineClassImpl(), should use ProtectionDomain */
571
Class<?> answer = defineClassImpl(className, classRep, offset, length, pd);
572
573
if (certs != null) {
574
setSigners(answer, certs);
575
}
576
577
boolean isVerbose = isVerboseImpl();
578
URL url = null;
579
if (isVerbose) {
580
if (pd != null) {
581
CodeSource cs = pd.getCodeSource();
582
if (cs != null) {
583
url = cs.getLocation();
584
}
585
}
586
}
587
/*[IF Sidecar19-SE]*/
588
addPackageToList(answer);
589
/*[ENDIF] Sidecar19-SE */
590
591
/*[PR CMVC 89001] Verbose output when loading non-bootstrap classes */
592
if (isVerbose) {
593
/*[PR CMVC 99348] Do not log to System.err */
594
String location = (url != null) ? url.toString() : "<unknown>"; //$NON-NLS-1$
595
com.ibm.oti.vm.VM.dumpString("class load: " + answer.getName() + " from: " + location + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
596
}
597
return answer;
598
}
599
600
/*[IF JAVA_SPEC_VERSION >= 15]*/
601
602
private final native Class<?> defineClassImpl1(Class<?> hostClass, String className, byte[] classRep, ProtectionDomain protectionDomain, boolean init, int flags, Object classData);
603
final Class<?> defineClassInternal(
604
Class<?> hostClass,
605
String className,
606
byte[] classRep,
607
ProtectionDomain protectionDomain,
608
boolean init,
609
int flags,
610
Object classData)
611
throws java.lang.ClassFormatError
612
{
613
Class<?> answer = defineClassImpl1(hostClass, className, classRep, protectionDomain, init, flags, classData);
614
return answer;
615
}
616
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
617
618
/*[IF Sidecar19-SE]*/
619
/**
620
* This class is a function that maps a package name to a newly created
621
* {@code NamedPackage} object for use below in updating the {@code packages} map.
622
*/
623
private static final class NamedPackageProvider implements java.util.function.Function<String, NamedPackage> {
624
625
private final Class<?> newClass;
626
627
NamedPackageProvider(Class<?> newClass) {
628
super();
629
this.newClass = newClass;
630
}
631
632
@Override
633
public NamedPackage apply(String pkgName) {
634
return new NamedPackage(pkgName, newClass.getModule());
635
}
636
637
}
638
639
/**
640
* Add a class's package name to this classloader's list of packages, if not already present.
641
* @param newClass
642
*/
643
void addPackageToList(Class<?> newClass) {
644
synchronized (packages) {
645
packages.computeIfAbsent(newClass.getPackageName(), new NamedPackageProvider(newClass));
646
}
647
}
648
/*[ENDIF] Sidecar19-SE */
649
650
/*[PR CMVC 89001] Verbose output when loading non-bootstrap classes */
651
private native boolean isVerboseImpl();
652
653
private static native boolean foundJavaAssertOption();
654
655
private void checkPackageSigners(final String packageName, String className, final Certificate[] classCerts) {
656
Certificate[] packageCerts = null;
657
synchronized(lazyInitLock) {
658
if (packageSigners != null) {
659
packageCerts = packageSigners.get(packageName);
660
} else {
661
packageSigners = new Hashtable<>();
662
}
663
}
664
if (packageCerts == null) {
665
if (classCerts == null) {
666
packageSigners.put(packageName, emptyCertificates);
667
} else {
668
packageSigners.put(packageName, classCerts);
669
670
}
671
} else {
672
if ((classCerts == null && packageCerts.length == 0) || classCerts == packageCerts)
673
return;
674
if (classCerts != null && classCerts.length == packageCerts.length) {
675
boolean foundMatch = true;
676
test: for (int i=0; i<classCerts.length; i++) {
677
if (classCerts[i] == packageCerts[i]) continue;
678
if (classCerts[i].equals(packageCerts[i])) continue;
679
for (int j=0; j<packageCerts.length; j++) {
680
if (j == i) continue;
681
if (classCerts[i] == packageCerts[j]) continue test;
682
if (classCerts[i].equals(packageCerts[j])) continue test;
683
}
684
foundMatch = false;
685
break;
686
}
687
if (foundMatch) return;
688
}
689
/*[MSG "K01d1", "Signers of '{0}' do not match signers of other classes in package"]*/
690
throw new SecurityException(com.ibm.oti.util.Msg.getString("K01d1", className)); //$NON-NLS-1$
691
}
692
}
693
694
/**
695
* Gets the current default protection domain. If there isn't
696
* one, it attempts to construct one based on the currently
697
* in place security policy.
698
* <p>
699
* If the default protection domain can not be determined,
700
* answers null.
701
* <p>
702
*
703
* @return ProtectionDomain or null
704
* the default protection domain.
705
*/
706
private final ProtectionDomain getDefaultProtectionDomain () {
707
if (isParallelCapable) {
708
if (defaultProtectionDomain == null) {
709
synchronized(lazyInitLock) {
710
return getDefaultProtectionDomainHelper();
711
}
712
}
713
return defaultProtectionDomain;
714
} else {
715
// no need for synchronisation when not parallel capable
716
return getDefaultProtectionDomainHelper();
717
}
718
}
719
720
private final ProtectionDomain getDefaultProtectionDomainHelper() {
721
if (defaultProtectionDomain == null) {
722
/*[PR 115587] Default 1.4 behavior is to create dynamic ProtectionDomains */
723
defaultProtectionDomain = new ProtectionDomain(defaultCodeSource, null, this, null);
724
}
725
return defaultProtectionDomain;
726
}
727
728
/*
729
* VM level support for constructing a new class. Should not
730
* be called by subclasses.
731
*/
732
private final native Class<?> defineClassImpl(String className, byte [] classRep, int offset, int length, Object protectionDomain);
733
734
735
/**
736
* Overridden by subclasses, by default throws ClassNotFoundException.
737
* This method is called by loadClass() after the parent ClassLoader
738
* has failed to find a loaded class of the same name.
739
*
740
* @return java.lang.Class
741
* the class or null.
742
* @param className String
743
* the name of the class to search for.
744
* @exception ClassNotFoundException
745
* always, unless overridden.
746
*/
747
protected Class<?> findClass (String className) throws ClassNotFoundException {
748
throw new ClassNotFoundException();
749
}
750
751
/*[IF Sidecar19-SE]*/
752
/**
753
* Overridden by subclasses that support the loading from modules.
754
* When the moduleName is null, the default implementation invokes findClass(String),
755
* attempts to find the class and return it, or returns null in case of ClassNotFoundException.
756
* When the moduleName is not null, the default implementation returns null.
757
* This method is called by Class.forName(Module module, String name).
758
*
759
* @return java.lang.Class
760
* the class or null.
761
* @param moduleName
762
* the name of the module from which the class is to be loaded.
763
* @param className String
764
* the name of the class to search for.
765
766
*/
767
protected Class<?> findClass(String moduleName, String className) {
768
Class<?> classFound = null;
769
if (moduleName == null) {
770
try {
771
classFound = findClass(className);
772
} catch (ClassNotFoundException e) {
773
// returns null if the class can't be found
774
}
775
}
776
return classFound;
777
}
778
/*[ENDIF] Sidecar19-SE */
779
780
/**
781
* Attempts to find and return a class which has already
782
* been loaded by the virtual machine. Note that the class
783
* may not have been linked and the caller should call
784
* resolveClass() on the result if necessary.
785
*
786
* @return java.lang.Class
787
* the class or null.
788
* @param className String
789
* the name of the class to search for.
790
*/
791
protected final Class<?> findLoadedClass (String className) {
792
/*[PR CMVC 124675] allow findLoadedClass to find arrays if magic system property set */
793
if (!allowArraySyntax) {
794
if (className != null && className.length() > 0 && className.charAt(0) == '[') {
795
return null;
796
}
797
}
798
return findLoadedClassImpl(className);
799
}
800
801
private native Class<?> findLoadedClassImpl(String className);
802
803
/**
804
* Attempts to load a class using the system class loader.
805
* Note that the class has already been linked.
806
*
807
* @return java.lang.Class
808
* the class which was loaded.
809
* @param className String
810
* the name of the class to search for.
811
* @exception ClassNotFoundException
812
* if the class can not be found.
813
*/
814
protected final Class<?> findSystemClass (String className) throws ClassNotFoundException {
815
return applicationClassLoader.loadClass(className);
816
}
817
818
/**
819
* Returns the specified ClassLoader's parent.
820
*
821
* @return java.lang.ClassLoader
822
* the class or null.
823
* @exception SecurityException
824
* if a security manager exists and it does not
825
* allow the parent loader to be retrieved.
826
*/
827
@CallerSensitive
828
public final ClassLoader getParent() {
829
@SuppressWarnings("removal")
830
SecurityManager security = System.getSecurityManager();
831
if (security != null) {
832
ClassLoader callersClassLoader = callerClassLoader();
833
/*[PR JAZZ103 76960] permission check is needed against the parent instead of this classloader */
834
if (needsClassLoaderPermissionCheck(callersClassLoader, parent)) {
835
security.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
836
}
837
}
838
return parent;
839
}
840
841
/**
842
* Answers an URL which can be used to access the resource
843
* described by resName, using the class loader's resource lookup
844
* algorithm. The default behavior is just to return null.
845
*
846
* @return URL
847
* the location of the resource.
848
* @param resName String
849
* the name of the resource to find.
850
*
851
* @see Class#getResource
852
*/
853
public URL getResource (String resName) {
854
URL result = null;
855
if (null == parent) {
856
/*[IF Sidecar19-SE]*/
857
result = BootLoader.findResource(resName);
858
/*[ELSE]
859
result = bootstrapClassLoader.findResource(resName);
860
/*[ENDIF]*/
861
} else {
862
result = parent.getResource(resName);
863
}
864
if (null == result) {
865
result = findResource(resName);
866
}
867
return result;
868
}
869
870
/*
871
* A sequence of two or more enumerations.
872
*/
873
private static final class CompoundEnumeration<T> implements Enumeration<T> {
874
875
private final Queue<Enumeration<T>> queue;
876
877
CompoundEnumeration(Enumeration<T> first, Enumeration<T> second) {
878
super();
879
if (first instanceof CompoundEnumeration<?>) {
880
queue = ((CompoundEnumeration<T>) first).queue;
881
} else {
882
queue = new LinkedList<>();
883
queue.add(first);
884
}
885
queue.add(second);
886
}
887
888
void append(Enumeration<T> element) {
889
queue.add(element);
890
}
891
892
@Override
893
public boolean hasMoreElements() {
894
for (;;) {
895
Enumeration<T> head = queue.peek();
896
897
if (head == null) {
898
return false;
899
}
900
901
if (head.hasMoreElements()) {
902
return true;
903
}
904
905
queue.remove();
906
}
907
}
908
909
@Override
910
public T nextElement() {
911
for (;;) {
912
Enumeration<T> head = queue.peek();
913
914
if (head == null) {
915
throw new NoSuchElementException();
916
}
917
918
if (head.hasMoreElements()) {
919
return head.nextElement();
920
}
921
922
queue.remove();
923
}
924
}
925
}
926
927
/**
928
* Answers an Enumeration of URL which can be used to access the resources
929
* described by resName, using the class loader's resource lookup
930
* algorithm.
931
*
932
* @param resName String
933
* the name of the resource to find.
934
935
* @return Enumeration
936
* the locations of the resources.
937
*
938
* @throws IOException when an error occurs
939
*/
940
public Enumeration<URL> getResources(String resName) throws IOException {
941
Enumeration<URL> resources = null;
942
943
/*[PR CMVC 198371] ClassLoader.getResources doesn't get override or Overridden get */
944
if (parent != null) {
945
resources = parent.getResources(resName);
946
} else if (this != bootstrapClassLoader) {
947
resources =
948
/*[IF Sidecar19-SE]*/
949
BootLoader.findResources(resName);
950
/*[ELSE]
951
bootstrapClassLoader.getResources(resName);
952
/*[ENDIF]*/
953
}
954
955
Enumeration<URL> localResources = findResources(resName);
956
957
if (localResources != null && !localResources.hasMoreElements()) {
958
localResources = null;
959
}
960
961
if (resources == null) {
962
resources = localResources;
963
if (resources == null) {
964
resources = Collections.emptyEnumeration();
965
}
966
} else if (localResources != null) {
967
if (resources instanceof CompoundEnumeration<?>) {
968
((CompoundEnumeration<URL>) resources).append(localResources);
969
} else {
970
resources = new CompoundEnumeration<>(resources, localResources);
971
}
972
}
973
974
return resources;
975
}
976
977
/**
978
* Answers a stream on a resource found by looking up
979
* resName using the class loader's resource lookup
980
* algorithm. The default behavior is just to return null.
981
*
982
* @return InputStream
983
* a stream on the resource or null.
984
* @param resName String
985
* the name of the resource to find.
986
*
987
* @see Class#getResourceAsStream
988
*/
989
public InputStream getResourceAsStream (String resName) {
990
URL url = getResource(resName);
991
try {
992
if (url != null) return url.openStream();
993
} catch (IOException e) {
994
// ignore
995
}
996
return null;
997
}
998
999
static void completeInitialization() {
1000
/*[PR JAZZ 57622: Support -Dreflect.cache=boot option] -Dreflect.cache=boot causes deadlock (Details: CMVC 120695). Loading Void class explicitly will prevent possible deadlock during caching reflect classes/methods. */
1001
@SuppressWarnings("unused")
1002
Class<?> voidClass = Void.TYPE;
1003
1004
/*[PR CMVC 193137] -Dreflect.cache=boot throws NPE. Caching reflect objects for bootstrap callers should be enabled late to avoid bootstrap problems. */
1005
/* Process reflect.cache=boot, other options are processed earlier in initializeClassLoaders() */
1006
String propValue = System.internalGetProperties().getProperty("reflect.cache"); //$NON-NLS-1$
1007
if (propValue != null) propValue = propValue.toLowerCase();
1008
/* Do not enable reflect cache if -Dreflect.cache=false is in commandline */
1009
boolean reflectCacheAppOnly = true;
1010
if (!"false".equals(propValue)) { //$NON-NLS-1$
1011
reflectCacheAppOnly = false;
1012
1013
if (propValue != null) {
1014
/*[PR 125873] Improve reflection cache */
1015
int bootIndex = propValue.indexOf("boot"); //$NON-NLS-1$
1016
if (bootIndex >= 0) {
1017
reflectCacheAppOnly = false;
1018
} else {
1019
int appIndex = propValue.indexOf("app"); //$NON-NLS-1$
1020
if (appIndex >= 0) {
1021
reflectCacheAppOnly = true;
1022
}
1023
}
1024
}
1025
}
1026
Class.setReflectCacheAppOnly(reflectCacheAppOnly);
1027
1028
initSystemClassLoader = true;
1029
}
1030
1031
/*[IF Sidecar18-SE-OpenJ9|Sidecar19-SE]*/
1032
//Returns incoming class's classloader without going through security checking
1033
static ClassLoader getClassLoader(Class<?> clz) {
1034
if (null != clz) {
1035
return clz.getClassLoader0();
1036
} else {
1037
return null;
1038
}
1039
}
1040
/*[ENDIF]*/
1041
1042
/*[IF Sidecar19-SE]*/
1043
/**
1044
* Return the Platform classloader.
1045
*
1046
* If a security manager exists and it does not
1047
* allow access a SecurityException will be thrown.
1048
*
1049
* @return the platformClassLoader
1050
* @throws SecurityException if access to the platform classloader is denied
1051
*/
1052
@CallerSensitive
1053
public static ClassLoader getPlatformClassLoader() {
1054
@SuppressWarnings("removal")
1055
SecurityManager security = System.getSecurityManager();
1056
ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
1057
if (security != null) {
1058
ClassLoader callersClassLoader = callerClassLoader();
1059
if (needsClassLoaderPermissionCheck(callersClassLoader, platformClassLoader)) {
1060
security.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1061
}
1062
}
1063
return platformClassLoader;
1064
}
1065
1066
// Loads a class in a module defined to this classloader
1067
// This method returns null if the class can't be found
1068
// Not delegate to the parent classloader
1069
final Class<?> loadLocalClass(java.lang.String name) {
1070
Class<?> localClass = null;
1071
try {
1072
localClass = loadClassHelper(name, false, false, null);
1073
} catch (ClassNotFoundException e) {
1074
// returns null if the class can't be found
1075
}
1076
return localClass;
1077
}
1078
1079
/**
1080
* Get the name given when creating the ClassLoader instance, or null if none was provided.
1081
* @return name of the class loader or null
1082
* @since 9
1083
*/
1084
public String getName() {
1085
return classLoaderName;
1086
}
1087
/*[ENDIF] Sidecar19-SE */
1088
1089
/**
1090
* Convenience operation to obtain a reference to the system class loader.
1091
* The system class loader is the parent of any new <code>ClassLoader</code>
1092
* objects created in the course of an application and will normally be the
1093
* same <code>ClassLoader</code> as that used to launch an application.
1094
*
1095
* @return java.lang.ClassLoader the system classLoader.
1096
* @exception SecurityException
1097
* if a security manager exists and it does not permit the
1098
* caller to access the system class loader.
1099
*/
1100
@CallerSensitive
1101
public static ClassLoader getSystemClassLoader () {
1102
/*[PR CMVC 99755] Implement -Djava.system.class.loader option */
1103
if (initSystemClassLoader) {
1104
Class<?> classLoaderClass = ClassLoader.class;
1105
synchronized(classLoaderClass) {
1106
if (initSystemClassLoader) {
1107
initSystemClassLoader = false;
1108
1109
String userLoader = System.internalGetProperties().getProperty("java.system.class.loader"); //$NON-NLS-1$
1110
if (userLoader != null) {
1111
try {
1112
Class<?> loaderClass = Class.forName(userLoader, true, applicationClassLoader);
1113
Constructor<?> constructor = loaderClass.getConstructor(new Class<?>[]{classLoaderClass});
1114
applicationClassLoader = (ClassLoader)constructor.newInstance(new Object[]{applicationClassLoader});
1115
/*[PR JAZZ103 87642] Setting -Djava.system.class.loader on the command line doesn't update VMAccess.setExtClassLoader() */
1116
/* Find the extension class loader */
1117
ClassLoader tempLoader = applicationClassLoader;
1118
while (tempLoader.parent != null) {
1119
tempLoader = tempLoader.parent;
1120
}
1121
VMAccess.setExtClassLoader(tempLoader);
1122
} catch (Throwable e) {
1123
if (e instanceof InvocationTargetException) {
1124
throw new Error(e.getCause());
1125
} else {
1126
throw new Error(e);
1127
}
1128
}
1129
}
1130
}
1131
}
1132
}
1133
1134
ClassLoader sysLoader = applicationClassLoader;
1135
@SuppressWarnings("removal")
1136
SecurityManager security = System.getSecurityManager();
1137
if (security != null) {
1138
ClassLoader callersClassLoader = callerClassLoader();
1139
if (needsClassLoaderPermissionCheck(callersClassLoader, sysLoader)) {
1140
security.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1141
}
1142
}
1143
1144
return sysLoader;
1145
}
1146
1147
/**
1148
* Answers an URL specifying a resource which can be found by
1149
* looking up resName using the system class loader's resource
1150
* lookup algorithm.
1151
*
1152
* @return URL
1153
* a URL specifying a system resource or null.
1154
* @param resName String
1155
* the name of the resource to find.
1156
*
1157
* @see Class#getResource
1158
*/
1159
public static URL getSystemResource(String resName) {
1160
return getSystemClassLoader().getResource(resName);
1161
}
1162
1163
/**
1164
* Answers an Enumeration of URL containing all resources which can be
1165
* found by looking up resName using the system class loader's resource
1166
* lookup algorithm.
1167
*
1168
* @param resName String
1169
* the name of the resource to find.
1170
*
1171
* @return Enumeration
1172
* an Enumeration of URL containing the system resources
1173
*
1174
* @throws IOException when an error occurs
1175
*/
1176
public static Enumeration<URL> getSystemResources(String resName) throws IOException {
1177
return getSystemClassLoader().getResources(resName);
1178
}
1179
1180
/**
1181
* Answers a stream on a resource found by looking up
1182
* resName using the system class loader's resource lookup
1183
* algorithm. Basically, the contents of the java.class.path
1184
* are searched in order, looking for a path which matches
1185
* the specified resource.
1186
*
1187
* @return a stream on the resource or null.
1188
* @param resName the name of the resource to find.
1189
*
1190
* @see Class#getResourceAsStream
1191
*/
1192
public static InputStream getSystemResourceAsStream(String resName) {
1193
return getSystemClassLoader().getResourceAsStream(resName);
1194
}
1195
1196
/*[IF Sidecar19-SE]*/
1197
/**
1198
* Answers the unnamed Module of this class loader.
1199
*
1200
* @return the unnamed Module of this class loader
1201
*/
1202
public final Module getUnnamedModule()
1203
{
1204
return this.unnamedModule;
1205
}
1206
/*[ENDIF] Sidecar19-SE */
1207
1208
/**
1209
* Invoked by the Virtual Machine when resolving class references.
1210
* Equivalent to loadClass(className, false);
1211
*
1212
* @return java.lang.Class
1213
* the Class object.
1214
* @param className String
1215
* the name of the class to search for.
1216
* @exception ClassNotFoundException
1217
* If the class could not be found.
1218
*/
1219
public Class<?> loadClass (String className) throws ClassNotFoundException {
1220
/*[IF Sidecar19-SE]*/
1221
if ((bootstrapClassLoader == null) || (this == bootstrapClassLoader)) {
1222
Class<?> cls = VMAccess.findClassOrNull(className, bootstrapClassLoader);
1223
if (cls == null) {
1224
throw new ClassNotFoundException(className);
1225
}
1226
return cls;
1227
}
1228
/*[ENDIF] Sidecar19-SE */
1229
return loadClass(className, false);
1230
}
1231
1232
/**
1233
* Attempts to load the type <code>className</code> in the running VM,
1234
* optionally linking the type after a successful load.
1235
*
1236
* @return java.lang.Class
1237
* the Class object.
1238
* @param className String
1239
* the name of the class to search for.
1240
* @param resolveClass boolean
1241
* indicates if class should be resolved after loading.
1242
* @exception ClassNotFoundException
1243
* If the class could not be found.
1244
*/
1245
/*[PR CMVC 180958] SVT:HRT:deadlock following class library change to classloader */
1246
protected Class<?> loadClass(final String className, boolean resolveClass) throws ClassNotFoundException {
1247
return loadClassHelper(className, resolveClass, true
1248
/*[IF Sidecar19-SE]*/
1249
, null
1250
/*[ENDIF]*/
1251
);
1252
}
1253
1254
/*[IF Sidecar19-SE]*/
1255
/**
1256
* Invoked by package access methods such as java.lang.Package.getPackageInfo()
1257
* resolveClass flag is false, delegateToParent flag is false as well.
1258
*
1259
* @param module Module
1260
* the module to search for
1261
* @param className String
1262
* the name of the class to search for
1263
* @exception NullPointerException
1264
* if the given module is null
1265
* @return java.lang.Class
1266
* the Class object
1267
*/
1268
final Class<?> loadClass(Module module, String className) {
1269
Class<?> localClass = null;
1270
1271
if ((bootstrapClassLoader == null) || (this == bootstrapClassLoader)) {
1272
localClass = VMAccess.findClassOrNull(className, bootstrapClassLoader);
1273
} else {
1274
try {
1275
localClass = loadClassHelper(className, false, false, module);
1276
} catch (ClassNotFoundException e) {
1277
// returns null if the class can't be found
1278
}
1279
}
1280
return localClass;
1281
}
1282
/*[ENDIF]*/
1283
/**
1284
* Attempts to load the type <code>className</code> in the running VM,
1285
* optionally linking the type after a successful load.
1286
*
1287
* @param className String
1288
* the name of the class to search for.
1289
* @param resolveClass boolean
1290
* indicates if class should be resolved after loading.
1291
* @param delegateToParent boolean
1292
* indicate if the parent classloader should be delegated for class loading
1293
* @param module
1294
* the module from which the class is to be loaded.
1295
* @exception ClassNotFoundException
1296
* If the class could not be found.
1297
* @return java.lang.Class
1298
* the Class object.
1299
*/
1300
Class<?> loadClassHelper(final String className, boolean resolveClass, boolean delegateToParent
1301
/*[IF Sidecar19-SE]*/
1302
, Module module
1303
/*[ENDIF]*/
1304
) throws ClassNotFoundException {
1305
Object lock = isParallelCapable ? getClassLoadingLock(className) : this;
1306
1307
synchronized (lock) {
1308
// Ask the VM to look in its cache.
1309
Class<?> loadedClass = findLoadedClass(className);
1310
// search in parent if not found
1311
if (loadedClass == null) {
1312
if (delegateToParent) {
1313
try {
1314
if (parent == null) {
1315
/*[PR 95894]*/
1316
if (isDelegatingCL) {
1317
loadedClass = bootstrapClassLoader.findLoadedClass(className);
1318
}
1319
if (loadedClass == null) {
1320
loadedClass = bootstrapClassLoader.loadClass(className);
1321
}
1322
} else {
1323
if (isDelegatingCL) {
1324
loadedClass = parent.findLoadedClass(className);
1325
}
1326
if (loadedClass == null) {
1327
loadedClass = parent.loadClass(className, resolveClass);
1328
}
1329
}
1330
} catch (ClassNotFoundException e) {
1331
// don't do anything. Catching this exception is the normal protocol for
1332
// parent classloaders telling use they couldn't find a class.
1333
}
1334
}
1335
1336
// not findLoadedClass or by parent.loadClass, try locally
1337
if (loadedClass == null) {
1338
/*[IF Sidecar19-SE]*/
1339
if (module == null) {
1340
/*[ENDIF]*/
1341
loadedClass = findClass(className);
1342
/*[IF Sidecar19-SE]*/
1343
}
1344
else {
1345
loadedClass = findClass(module.getName(), className);
1346
}
1347
/*[ENDIF]*/
1348
}
1349
}
1350
1351
/*[IF Sidecar19-SE]*/
1352
if (module != null && loadedClass != null) {
1353
Module moduleLoadedClass = loadedClass.getModule();
1354
if (module != moduleLoadedClass) {
1355
return null;
1356
}
1357
}
1358
/*[ENDIF]*/
1359
1360
// resolve if required
1361
if (resolveClass) resolveClass(loadedClass);
1362
return loadedClass;
1363
}
1364
}
1365
1366
/**
1367
* Attempts to register the ClassLoader as being capable of
1368
* parallel class loading. This requires that all superclasses must
1369
* also be parallel capable.
1370
*
1371
* @return True if the ClassLoader successfully registers as
1372
* parallel capable, false otherwise.
1373
*
1374
* @see java.lang.ClassLoader
1375
*/
1376
@CallerSensitive
1377
protected static boolean registerAsParallelCapable() {
1378
final Class<?> callerCls = System.getCallerClass();
1379
1380
/*[IF JAVA_SPEC_VERSION >= 18]*/
1381
return registerAsParallelCapable(callerCls);
1382
/*[ELSE] JAVA_SPEC_VERSION >= 18
1383
if (parallelCapableCollection.containsKey(callerCls)) {
1384
return true;
1385
}
1386
1387
Class<?> superCls = callerCls.getSuperclass();
1388
1389
if (superCls == ClassLoader.class || parallelCapableCollection.containsKey(superCls)) {
1390
parallelCapableCollection.put(callerCls, null);
1391
return true;
1392
}
1393
1394
return false;
1395
/*[ENDIF] JAVA_SPEC_VERSION >= 18 */
1396
}
1397
1398
/*[IF JAVA_SPEC_VERSION >= 18]*/
1399
@CallerSensitiveAdapter
1400
private static boolean registerAsParallelCapable(Class<?> callerCls) {
1401
if (parallelCapableCollection.containsKey(callerCls)) {
1402
return true;
1403
}
1404
1405
Class<?> superCls = callerCls.getSuperclass();
1406
1407
if (superCls == ClassLoader.class || parallelCapableCollection.containsKey(superCls)) {
1408
parallelCapableCollection.put(callerCls, null);
1409
return true;
1410
}
1411
1412
return false;
1413
}
1414
/*[ENDIF] JAVA_SPEC_VERSION >= 18 */
1415
1416
/**
1417
* Answers the lock object for class loading in parallel.
1418
* If this ClassLoader object has been registered as parallel capable,
1419
* a dedicated object associated with this specified class name is returned.
1420
* Otherwise, current ClassLoader object is returned.
1421
*
1422
* @param className String
1423
* name of the to be loaded class
1424
*
1425
* @return the lock for class loading operations
1426
*
1427
* @exception NullPointerException
1428
* if registered as parallel capable and className is null
1429
*
1430
* @see java.lang.ClassLoader
1431
*
1432
*/
1433
protected Object getClassLoadingLock(final String className) {
1434
Object lock = this;
1435
if (isParallelCapable) {
1436
if (classNameBasedLock == null) {
1437
synchronized(lazyInitLock) {
1438
if (classNameBasedLock == null) {
1439
classNameBasedLock = new Hashtable<>();
1440
}
1441
}
1442
}
1443
synchronized(classNameBasedLock) {
1444
// get() does null pointer check
1445
ClassNameLockRef wf = classNameBasedLock.get(className);
1446
lock = (null != wf) ? wf.get() : null;
1447
if (lock == null) {
1448
lock = new ClassNameBasedLock();
1449
classNameBasedLock.put(className, new ClassNameLockRef(lock, className, classNameBasedLock));
1450
}
1451
}
1452
}
1453
return lock;
1454
}
1455
1456
1457
/**
1458
* Forces a class to be linked (initialized). If the class has
1459
* already been linked this operation has no effect.
1460
*
1461
* @param clazz Class
1462
* the Class to link.
1463
* @exception NullPointerException
1464
* if clazz is null.
1465
*
1466
* @see Class#getResource
1467
*/
1468
protected final void resolveClass(Class<?> clazz) {
1469
if (clazz == null)
1470
throw new NullPointerException();
1471
}
1472
1473
/**
1474
* Forces the parent of a classloader instance to be newParent
1475
*
1476
* @param newParent ClassLoader
1477
* the ClassLoader to make the parent.
1478
*/
1479
private void setParent(ClassLoader newParent) {
1480
parent = newParent;
1481
}
1482
1483
/**
1484
* Answers true if the receiver is a system class loader.
1485
* <p>
1486
* Note that this method has package visibility only. It is
1487
* defined here to avoid the security manager check in
1488
* getSystemClassLoader, which would be required to implement
1489
* this method anywhere else.
1490
*
1491
* @return boolean
1492
* true if the receiver is a system class loader
1493
*
1494
* @see Class#getClassLoaderImpl()
1495
*/
1496
final boolean isASystemClassLoader() {
1497
/*[IF]
1498
1FDVFL7: J9JCL:ALL - isASystemClassLoader should check starting at appClassLoader.
1499
/*[ENDIF]*/
1500
if (this == bootstrapClassLoader) return true;
1501
ClassLoader cl = applicationClassLoader;
1502
while (cl != null) {
1503
if (this == cl) return true;
1504
cl = cl.parent;
1505
}
1506
return false;
1507
}
1508
1509
/**
1510
* Answers true if the receiver is ancestor of another class loader.
1511
* <p>
1512
* Note that this method has package visibility only. It is
1513
* defined here to avoid the security manager check in
1514
* getParent, which would be required to implement
1515
* this method anywhere else.
1516
*
1517
* @param child ClassLoader, a child candidate
1518
*
1519
* @return boolean
1520
* true if the receiver is ancestor of the parameter
1521
*/
1522
final boolean isAncestorOf (ClassLoader child) {
1523
if (child == null) return false;
1524
if (this == bootstrapClassLoader) return true;
1525
ClassLoader cl = child.parent;
1526
while (cl != null) {
1527
if (this == cl) return true;
1528
cl = cl.parent;
1529
}
1530
return false;
1531
}
1532
1533
1534
/**
1535
* A class loader 'callerClassLoader' can access class loader 'requested' without permission check
1536
* if any of the following are true
1537
* (1) if class loader 'callerClassLoader' is same as class loader 'requested' or
1538
* (2) if 'callerClassLoader' is an ancestor of 'requested'.
1539
* (3) a 'callerClassLoader' in a system domain can access any class loader.
1540
*
1541
* @param callerClassLoader the calling ClassLoader
1542
* @param requested the ClassLoader being requested
1543
* @return boolean indicating if a security check is required
1544
*/
1545
static final boolean needsClassLoaderPermissionCheck(ClassLoader callerClassLoader, ClassLoader requested) {
1546
return callerClassLoader != null &&
1547
callerClassLoader != requested && !callerClassLoader.isAncestorOf(requested);
1548
}
1549
1550
/**
1551
* Answers an URL which can be used to access the resource
1552
* described by resName, using the class loader's resource lookup
1553
* algorithm. The default behavior is just to return null.
1554
* This should be implemented by a ClassLoader.
1555
*
1556
* @return URL
1557
* the location of the resource.
1558
* @param resName String
1559
* the name of the resource to find.
1560
*/
1561
protected URL findResource (String resName) {
1562
return null;
1563
}
1564
1565
/**
1566
* Answers an Enumeration of URL which can be used to access the resources
1567
* described by resName, using the class loader's resource lookup
1568
* algorithm. The default behavior is just to return an empty Enumeration.
1569
*
1570
* @param resName String
1571
* the name of the resource to find.
1572
* @return Enumeration
1573
* the locations of the resources.
1574
*
1575
* @throws IOException when an error occurs
1576
*/
1577
protected Enumeration<URL> findResources (String resName) throws IOException {
1578
return new Vector<URL>().elements();
1579
}
1580
1581
/**
1582
* Answers the absolute path of the file containing the library
1583
* associated with the given name, or null. If null is answered,
1584
* the system searches the directories specified by the system
1585
* property "java.library.path".
1586
*
1587
* @return String
1588
* the library file name or null.
1589
* @param libName String
1590
* the name of the library to find.
1591
*/
1592
protected String findLibrary(String libName) {
1593
return null;
1594
}
1595
1596
/**
1597
* Answers a package of given name defined by this ClassLoader.
1598
*
1599
* @param name The name of the package to find
1600
*
1601
* @return The package requested
1602
*/
1603
/*[IF Sidecar19-SE]*/
1604
public
1605
/*[ENDIF]*/
1606
final Package getDefinedPackage(String name) {
1607
/*[IF Sidecar19-SE]*/
1608
Package pkg = null;
1609
synchronized(packages) {
1610
NamedPackage np = packages.get(name);
1611
if (null != np) {
1612
if (np instanceof Package) {
1613
pkg = (Package)np;
1614
} else {
1615
pkg = NamedPackage.toPackage(np.packageName(), np.module());
1616
packages.put(name, pkg);
1617
}
1618
}
1619
}
1620
return pkg;
1621
/*[ELSE]*/
1622
return packages.get(name);
1623
/*[ENDIF] Sidecar19-SE*/
1624
}
1625
1626
/*[IF Sidecar19-SE]*/
1627
/**
1628
* Answers all the packages defined by this classloader.
1629
*
1630
* @return Array of Package objects or zero length array if no package is defined
1631
*/
1632
public final Package[] getDefinedPackages() {
1633
synchronized(packages) {
1634
if (packages.isEmpty()) {
1635
return EMPTY_PACKAGE_ARRAY;
1636
} else {
1637
return packages().toArray(Package[]::new);
1638
}
1639
}
1640
}
1641
/*[ENDIF] Sidecar19-SE*/
1642
/**
1643
* Attempt to locate the requested package. If no package information
1644
* can be located, null is returned.
1645
*
1646
* @param name The name of the package to find
1647
* @return The package requested, or null
1648
/*[IF Sidecar19-SE]
1649
*
1650
* @deprecated Use getDefinedPackage(String)
1651
/*[ENDIF]
1652
*/
1653
/*[IF Sidecar19-SE]*/
1654
@Deprecated(forRemoval=false, since="9")
1655
/*[ENDIF]*/
1656
protected Package getPackage(String name) {
1657
if (this == bootstrapClassLoader) {
1658
/*[IF Sidecar19-SE]*/
1659
return BootLoader.getDefinedPackage(name);
1660
/*[ELSE]*/
1661
return getDefinedPackage(name);
1662
/*[ENDIF]*/
1663
} else {
1664
Package p = getDefinedPackage(name);
1665
if (p == null) {
1666
ClassLoader parentLoader = this.parent;
1667
if (parentLoader == null) {
1668
parentLoader = bootstrapClassLoader;
1669
}
1670
p = parentLoader.getPackage(name);
1671
}
1672
return p;
1673
}
1674
}
1675
1676
private Package[] getPackagesHelper(
1677
/*[IF Sidecar19-SE]*/
1678
Hashtable<?, NamedPackage>
1679
/*[ELSE]
1680
Hashtable<?, Package>
1681
/*[ENDIF] Sidecar19-SE*/
1682
localPackages, Package[] ancestorsPackages) {
1683
int resultSize = localPackages.size();
1684
if (ancestorsPackages != null) {
1685
resultSize += ancestorsPackages.length;
1686
}
1687
Package[] result = new Package[resultSize];
1688
int i = 0;
1689
if (ancestorsPackages != null) {
1690
i = ancestorsPackages.length;
1691
System.arraycopy(ancestorsPackages, 0, result, 0, i);
1692
}
1693
1694
/*[IF Sidecar19-SE]*/
1695
Package[] pkgs = packages().toArray(Package[]::new);
1696
System.arraycopy(pkgs, 0, result, i, pkgs.length);
1697
/*[ELSE]
1698
Enumeration<Package> myPkgs = localPackages.elements();
1699
while (myPkgs.hasMoreElements()) {
1700
result[i++] = myPkgs.nextElement();
1701
}
1702
/*[ENDIF] Sidecar19-SE*/
1703
1704
return result;
1705
}
1706
1707
/**
1708
* Answers all the packages known to this class loader.
1709
*
1710
* @return All the packages known to this classloader
1711
*/
1712
protected Package[] getPackages() {
1713
/*[IF Sidecar19-SE]*/
1714
if (this == bootstrapClassLoader) {
1715
return BootLoader.packages().toArray(Package[]::new);
1716
}
1717
/*[ENDIF]*/
1718
1719
Package[] ancestorsPackages = null;
1720
if (parent == null) {
1721
/*[IF !Sidecar19-SE]*/
1722
if (this != bootstrapClassLoader) {
1723
/*[ENDIF]*/
1724
ancestorsPackages = bootstrapClassLoader.getPackages();
1725
/*[IF !Sidecar19-SE]*/
1726
}
1727
/*[ENDIF]*/
1728
} else {
1729
ancestorsPackages = parent.getPackages();
1730
}
1731
1732
/*[IF Sidecar19-SE]*/
1733
Hashtable<?, NamedPackage> localPackages = packages;
1734
/*[ELSE]
1735
Hashtable<?, Package> localPackages = packages;
1736
/*[ENDIF] Sidecar19-SE*/
1737
1738
boolean rtExceptionThrown = false;
1739
do {
1740
try {
1741
Package[] result;
1742
/*[IF Sidecar19-SE]*/
1743
if (rtExceptionThrown) {
1744
synchronized(packages) {
1745
result = getPackagesHelper(localPackages, ancestorsPackages);
1746
}
1747
} else {
1748
/*[ENDIF] Sidecar19-SE*/
1749
result = getPackagesHelper(localPackages, ancestorsPackages);
1750
/*[IF Sidecar19-SE]*/
1751
}
1752
/*[ENDIF] Sidecar19-SE*/
1753
return result;
1754
} catch(RuntimeException ex) {
1755
if (rtExceptionThrown) {
1756
throw ex;
1757
}
1758
rtExceptionThrown = true;
1759
/*[IF !Sidecar19-SE]*/
1760
localPackages = (Hashtable<?, Package>)packages.clone();
1761
/*[ENDIF] Sidecar19-SE*/
1762
}
1763
} while (true);
1764
}
1765
1766
/**
1767
* Define a new Package using the specified information.
1768
*
1769
* @param name The name of the package
1770
* @param specTitle The title of the specification for the Package
1771
* @param specVersion The version of the specification for the Package
1772
* @param specVendor The vendor of the specification for the Package
1773
* @param implTitle The implementation title of the Package
1774
* @param implVersion The implementation version of the Package
1775
* @param implVendor The specification vendor of the Package
1776
* @param sealBase The URL used to seal the Package, if null the Package is not sealed
1777
*
1778
* @return The Package created
1779
*
1780
* @exception IllegalArgumentException if the Package already exists
1781
*/
1782
protected Package definePackage(
1783
final String name, final String specTitle,
1784
final String specVersion, final String specVendor,
1785
final String implTitle, final String implVersion,
1786
final String implVendor, final URL sealBase)
1787
throws IllegalArgumentException
1788
{
1789
synchronized(packages) {
1790
/*[IF Sidecar19-SE]*/
1791
if (packages.containsKey(name)) {
1792
/*[ELSE]
1793
if (null != getPackage(name)) {
1794
/*[ENDIF]*/
1795
/*[MSG "K0053", "Package {0} already defined."]*/
1796
throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K0053", name)); //$NON-NLS-1$
1797
} else {
1798
Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase, this);
1799
packages.put(name, newPackage);
1800
return newPackage;
1801
}
1802
}
1803
}
1804
1805
/**
1806
* Gets the signers of a class.
1807
*
1808
* @param c The Class object
1809
* @return signers The signers for the class
1810
*/
1811
final Object[] getSigners(Class<?> c) {
1812
Hashtable<Class<?>, Object[]> localSigners = classSigners;
1813
if (localSigners == null) {
1814
synchronized (lazyInitLock) {
1815
localSigners = classSigners;
1816
if (localSigners == null) {
1817
return null;
1818
}
1819
}
1820
}
1821
Object[] result = localSigners.get(c);
1822
if (result != null) {
1823
result = result.clone();
1824
}
1825
return result;
1826
}
1827
1828
/**
1829
* Sets the signers of a class.
1830
*
1831
* @param c The Class object
1832
* @param signers The signers for the class
1833
*/
1834
1835
protected final void setSigners(final Class<?> c, final Object[] signers) {
1836
/*[PR CMVC 93861] setSigners() throws NullPointerException */
1837
if (c.getClassLoaderImpl() == this) {
1838
if (signers == null) {
1839
if (classSigners == null) {
1840
synchronized(lazyInitLock) {
1841
if (classSigners == null) {
1842
return;
1843
}
1844
}
1845
}
1846
classSigners.remove(c);
1847
} else {
1848
if (classSigners == null) {
1849
synchronized(lazyInitLock) {
1850
if (classSigners == null) {
1851
classSigners = new Hashtable<>();
1852
}
1853
}
1854
}
1855
classSigners.put(c, signers);
1856
}
1857
/*[PR 28064] Class.getSigner() method returns null */
1858
/*[PR CMVC 93861] setSigners() throws NullPointerException */
1859
} else c.getClassLoaderImpl().setSigners(c, signers);
1860
1861
}
1862
1863
@CallerSensitive
1864
static ClassLoader getCallerClassLoader() {
1865
ClassLoader loader = getStackClassLoader(2);
1866
if (loader == bootstrapClassLoader) return null;
1867
return loader;
1868
}
1869
1870
/**
1871
* Returns the ClassLoader of the method (including natives) at the
1872
* specified depth on the stack of the calling thread. Frames representing
1873
* the VM implementation of java.lang.reflect are not included in the list.
1874
*
1875
* Notes: <ul>
1876
* <li> This method operates on the defining classes of methods on stack.
1877
* NOT the classes of receivers. </li>
1878
*
1879
* <li> The item at depth zero is the caller of this method </li>
1880
* </ul>
1881
*
1882
* @param depth the stack depth of the requested ClassLoader
1883
* @return the ClassLoader at the specified depth
1884
*
1885
* @see com.ibm.oti.vm.VM#getStackClassLoader
1886
*/
1887
@CallerSensitive
1888
static final native ClassLoader getStackClassLoader(int depth);
1889
1890
/**
1891
* Returns the ClassLoader of the method that called the caller.
1892
* i.e. A.x() calls B.y() calls callerClassLoader(),
1893
* A's ClassLoader will be returned. Returns null for the
1894
* bootstrap ClassLoader.
1895
*
1896
* @return a ClassLoader or null for the bootstrap ClassLoader
1897
*/
1898
@CallerSensitive
1899
static ClassLoader callerClassLoader() {
1900
ClassLoader loader = getStackClassLoader(2);
1901
if (loader == bootstrapClassLoader) return null;
1902
return loader;
1903
}
1904
1905
/**
1906
* Loads and links the library specified by the argument.
1907
*
1908
* @param libName the name of the library to load
1909
* @param loader the classloader in which to load the library
1910
*
1911
* @exception UnsatisfiedLinkError
1912
* if the library could not be loaded
1913
* @exception SecurityException
1914
* if the library was not allowed to be loaded
1915
*/
1916
static void loadLibraryWithClassLoader(String libName, ClassLoader loader) {
1917
if (loader != null) {
1918
String realLibName = loader.findLibrary(libName);
1919
1920
if (realLibName != null) {
1921
loadLibraryWithPath(realLibName, loader, null);
1922
return;
1923
}
1924
}
1925
/*
1926
* [PR JAZZ 93728] Match behaviour of System.loadLibrary() in reference
1927
* implementation when system property java.library.path is set
1928
*/
1929
try {
1930
loadLibraryWithPath(libName, loader, System.internalGetProperties().getProperty("com.ibm.oti.vm.bootstrap.library.path")); //$NON-NLS-1$
1931
} catch (UnsatisfiedLinkError ule) {
1932
if (loader == null) {
1933
throw ule;
1934
} else {
1935
loadLibraryWithPath(libName, loader, System.internalGetProperties().getProperty("java.library.path")); //$NON-NLS-1$
1936
}
1937
}
1938
}
1939
1940
/**
1941
* Loads and links the library specified by the argument.
1942
* No security check is done.
1943
*
1944
* @param libName the name of the library to load
1945
* @param loader the classloader in which to load the library
1946
* @param libraryPath the library path to search, or null
1947
*
1948
* @exception UnsatisfiedLinkError
1949
* if the library could not be loaded
1950
*/
1951
static void loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath) {
1952
/*[PR 137143] - failure to load library, need to strip leading '/' on Windows platforms, if present */
1953
if (File.separatorChar == '\\'){
1954
if (libName.startsWith("/") && com.ibm.oti.util.Util.startsWithDriveLetter(libName.substring(1))){ //$NON-NLS-1$
1955
libName = libName.substring(1);
1956
}
1957
}
1958
byte[] message = ClassLoader.loadLibraryWithPath(com.ibm.oti.util.Util.getBytes(libName), loader, libraryPath == null ? null : com.ibm.oti.util.Util.getBytes(libraryPath));
1959
1960
/* As Mac OS X used to be using lib<name>.jnilib Java native library format,
1961
* VM will attempt loading native library using the legacy library extension
1962
* on Mac OS X to support older applications
1963
*/
1964
if (System.internalGetProperties().getProperty("os.name").equals("Mac OS X")) { //$NON-NLS-1$ //$NON-NLS-2$
1965
if ((message != null) && (libraryPath != null)) {
1966
String legacyPath = libraryPath.replaceAll("/$", "") + "/lib" + libName + ".jnilib"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
1967
1968
try {
1969
byte[] jnilibLoadMessage = ClassLoader.loadLibraryWithPath(com.ibm.oti.util.Util.getBytes(legacyPath), loader, null);
1970
if (jnilibLoadMessage == null) {
1971
message = null;
1972
}
1973
} catch (Exception e) { /* Ignore Exception */ }
1974
}
1975
}
1976
1977
if (message != null) {
1978
String error;
1979
try {
1980
error = com.ibm.oti.util.Util.convertFromUTF8(message, 0, message.length);
1981
} catch (java.io.IOException e) {
1982
error = com.ibm.oti.util.Util.toString(message);
1983
}
1984
/*[MSG "K0649", "{0} ({1})"]*/
1985
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0649", libName, error));//$NON-NLS-1$
1986
1987
}
1988
}
1989
1990
private static synchronized native byte[] loadLibraryWithPath(byte[] libName, ClassLoader loader, byte[] libraryPath);
1991
1992
static void loadLibrary(Class<?> caller, String name, boolean fullPath) {
1993
if (fullPath)
1994
loadLibraryWithPath(name, caller.getClassLoaderImpl(), null);
1995
else
1996
loadLibraryWithClassLoader(name, caller.getClassLoaderImpl());
1997
}
1998
1999
/*[IF JAVA_SPEC_VERSION >= 15]*/
2000
static void loadLibrary(Class<?> caller, File file) {
2001
ClassLoader loader = (caller == null) ? null : caller.getClassLoader();
2002
NativeLibraries nls = (loader == null) ? BootLoader.getNativeLibraries() : loader.nativelibs;
2003
NativeLibrary nl = nls.loadLibrary(caller, file);
2004
if (nl == null) {
2005
/*[MSG "K0647", "Can't load {0}"]*/
2006
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0647", file));//$NON-NLS-1$
2007
}
2008
}
2009
static void loadLibrary(Class<?> caller, String libName) {
2010
ClassLoader loader = (caller == null) ? null : caller.getClassLoader();
2011
if (loader == null) {
2012
NativeLibrary nl = BootLoader.getNativeLibraries().loadLibrary(caller, libName);
2013
if (nl == null) {
2014
/*[MSG "K0647", "Can't load {0}"]*/
2015
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0647", libName));//$NON-NLS-1$
2016
}
2017
} else {
2018
NativeLibraries nls = loader.nativelibs;
2019
String libfilename = loader.findLibrary(libName);
2020
if (libfilename != null) {
2021
File libfile = new File(libfilename);
2022
if (!libfile.isAbsolute()) {
2023
/*[MSG "K0648", "Not an absolute path: {0}"]*/
2024
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0648", libfilename));//$NON-NLS-1$
2025
}
2026
NativeLibrary nl = nls.loadLibrary(caller, libfile);
2027
if (nl == null) {
2028
/*[MSG "K0647", "Can't load {0}"]*/
2029
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0647", libfilename));//$NON-NLS-1$
2030
}
2031
} else {
2032
NativeLibrary nl = nls.loadLibrary(caller, libName);
2033
if (nl == null) {
2034
/*[MSG "K0647", "Can't load {0}"]*/
2035
throw new UnsatisfiedLinkError(com.ibm.oti.util.Msg.getString("K0647", libName));//$NON-NLS-1$
2036
}
2037
}
2038
}
2039
}
2040
2041
static long findNative(ClassLoader loader, String entryName) {
2042
NativeLibraries nativelib;
2043
if ((loader == null) || (loader == bootstrapClassLoader)) {
2044
nativelib = BootLoader.getNativeLibraries();
2045
} else {
2046
nativelib = loader.nativelibs;
2047
}
2048
return nativelib.find(entryName);
2049
}
2050
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
2051
2052
/**
2053
* Sets the assertion status of a class.
2054
*
2055
* @param cname Class name
2056
* @param enable Enable or disable assertion
2057
*
2058
* @since 1.4
2059
*/
2060
public void setClassAssertionStatus(String cname, boolean enable) {
2061
setClassAssertionStatusImpl(cname, enable);
2062
}
2063
2064
private void setClassAssertionStatusImpl(String cname, boolean enable) {
2065
if (!isParallelCapable) {
2066
synchronized(this) {
2067
setClassAssertionStatusHelper(cname, enable);
2068
}
2069
} else {
2070
synchronized(assertionLock) {
2071
setClassAssertionStatusHelper(cname, enable);
2072
}
2073
}
2074
}
2075
2076
private void setClassAssertionStatusHelper(final String cname, final boolean enable) {
2077
if (classAssertionStatus == null ) {
2078
classAssertionStatus = new HashMap<>();
2079
}
2080
classAssertionStatus.put(cname, Boolean.valueOf(enable));
2081
}
2082
2083
/**
2084
* Sets the assertion status of a package.
2085
*
2086
* @param pname Package name
2087
* @param enable Enable or disable assertion
2088
*
2089
* @since 1.4
2090
*/
2091
public void setPackageAssertionStatus(String pname, boolean enable) {
2092
setPackageAssertionStatusImpl(pname, enable);
2093
}
2094
2095
private void setPackageAssertionStatusImpl(String pname, boolean enable) {
2096
if (!isParallelCapable) {
2097
synchronized(this) {
2098
setPackageAssertionStatusHelper(pname, enable);
2099
}
2100
} else {
2101
synchronized(assertionLock) {
2102
setPackageAssertionStatusHelper(pname, enable);
2103
}
2104
}
2105
}
2106
2107
private void setPackageAssertionStatusHelper(final String pname, final boolean enable) {
2108
if (packageAssertionStatus == null ) {
2109
packageAssertionStatus = new HashMap<>();
2110
}
2111
packageAssertionStatus.put(pname, Boolean.valueOf(enable));
2112
2113
}
2114
2115
/**
2116
* Sets the default assertion status of a classloader
2117
*
2118
* @param enable Enable or disable assertion
2119
*
2120
* @since 1.4
2121
*/
2122
public void setDefaultAssertionStatus(boolean enable){
2123
setDefaultAssertionStatusImpl(enable);
2124
}
2125
2126
private void setDefaultAssertionStatusImpl(boolean enable){
2127
if (!isParallelCapable) {
2128
synchronized(this) {
2129
defaultAssertionStatus = enable;
2130
}
2131
} else {
2132
synchronized(assertionLock) {
2133
defaultAssertionStatus = enable;
2134
}
2135
}
2136
}
2137
2138
/**
2139
* Clears the default, package and class assertion status of a classloader
2140
*
2141
* @since 1.4
2142
*/
2143
public void clearAssertionStatus(){
2144
if (!isParallelCapable) {
2145
synchronized(this) {
2146
defaultAssertionStatus = false;
2147
classAssertionStatus = null;
2148
packageAssertionStatus = null;
2149
}
2150
} else {
2151
synchronized(assertionLock) {
2152
defaultAssertionStatus = false;
2153
classAssertionStatus = null;
2154
packageAssertionStatus = null;
2155
}
2156
}
2157
}
2158
2159
/**
2160
* Answers the assertion status of the named class
2161
*
2162
* Returns the assertion status of the class or nested class if it has
2163
* been set. Otherwise returns the assertion status of its package or
2164
* superpackage if that has been set. Otherwise returns the default assertion
2165
* status.
2166
* Returns 1 for enabled and 0 for disabled.
2167
*
2168
* @param cname String
2169
* the name of class.
2170
*
2171
* @return int
2172
* the assertion status.
2173
*
2174
* @since 1.4
2175
*/
2176
boolean getClassAssertionStatus(String cname) {
2177
if (!isParallelCapable) {
2178
synchronized(this) {
2179
return getClassAssertionStatusHelper(cname);
2180
}
2181
} else {
2182
synchronized(assertionLock) {
2183
return getClassAssertionStatusHelper(cname);
2184
}
2185
}
2186
}
2187
private boolean getClassAssertionStatusHelper(String cname) {
2188
int dlrIndex = -1;
2189
2190
if (classAssertionStatus != null) {
2191
Boolean b = classAssertionStatus.get(cname);
2192
if (b != null) {
2193
return b.booleanValue();
2194
} else if ((dlrIndex = cname.indexOf('$'))>0) {
2195
b = classAssertionStatus.get(cname.substring(0, dlrIndex));
2196
if (b !=null)
2197
return b.booleanValue();
2198
}
2199
}
2200
/*[PR CMVC 80253] package assertion status not checked */
2201
if ((dlrIndex = cname.lastIndexOf('.'))>0) {
2202
return getPackageAssertionStatus(cname.substring(0, dlrIndex));
2203
}
2204
return getDefaultAssertionStatus();
2205
}
2206
2207
2208
/**
2209
* Answers the assertion status of the named package
2210
*
2211
* Returns the assertion status of the named package or superpackage if
2212
* that has been set. Otherwise returns the default assertion status.
2213
* Returns 1 for enabled and 0 for disabled.
2214
*
2215
* @param pname String
2216
* the name of package.
2217
*
2218
* @return int
2219
* the assertion status.
2220
*
2221
* @since 1.4
2222
*/
2223
boolean getPackageAssertionStatus(String pname) {
2224
if (!isParallelCapable) {
2225
synchronized(this) {
2226
return getPackageAssertionStatusHelper(pname);
2227
}
2228
} else {
2229
synchronized(assertionLock) {
2230
return getPackageAssertionStatusHelper(pname);
2231
}
2232
}
2233
}
2234
private boolean getPackageAssertionStatusHelper(String pname) {
2235
int prdIndex = -1;
2236
2237
if (packageAssertionStatus != null) {
2238
Boolean b = packageAssertionStatus.get(pname);
2239
if (b != null) {
2240
return b.booleanValue();
2241
} else if ((prdIndex = pname.lastIndexOf('.'))>0) {
2242
return getPackageAssertionStatus(pname.substring(0, prdIndex));
2243
}
2244
}
2245
return getDefaultAssertionStatus();
2246
}
2247
2248
/**
2249
* Answers the default assertion status
2250
*
2251
* @return boolean
2252
* the default assertion status.
2253
*
2254
* @since 1.4
2255
*/
2256
boolean getDefaultAssertionStatus() {
2257
if (!isParallelCapable) {
2258
synchronized(this) {
2259
return defaultAssertionStatus;
2260
}
2261
} else {
2262
synchronized(assertionLock) {
2263
return defaultAssertionStatus;
2264
}
2265
}
2266
}
2267
2268
/**
2269
* This sets the assertion status based on the commandline args to VM
2270
*
2271
* @since 1.4
2272
*/
2273
private void initializeClassLoaderAssertStatus() {
2274
/*[PR CMVC 130382] Optimize checking ClassLoader assertion status */
2275
/*[IF Sidecar19-SE]*/
2276
boolean bootLoader = bootstrapClassLoader == this;
2277
/*[ELSE]
2278
boolean bootLoader = bootstrapClassLoader == null;
2279
/*[ENDIF]*/
2280
2281
if (!bootLoader && !checkAssertionOptions) {
2282
// if the bootLoader didn't find any assertion options, other
2283
// classloaders can skip the check for options
2284
return;
2285
}
2286
2287
boolean foundAssertionOptions = false;
2288
String [] vmargs = com.ibm.oti.vm.VM.getVMArgs();
2289
for (int i=0; i<vmargs.length; i++) {
2290
if (!vmargs[i].startsWith("-e") && !vmargs[i].startsWith("-d")) { //$NON-NLS-1$ //$NON-NLS-2$
2291
continue;
2292
}
2293
// splice around :
2294
int indexColon = vmargs[i].indexOf(':');
2295
String vmargOptions, vmargExtraInfo;
2296
if ( indexColon == -1 ) {
2297
vmargOptions = vmargs[i];
2298
vmargExtraInfo = null;
2299
} else {
2300
vmargOptions = vmargs[i].substring(0, indexColon);
2301
vmargExtraInfo = vmargs[i].substring(indexColon+1);
2302
}
2303
if ( vmargOptions.compareTo("-ea") == 0 //$NON-NLS-1$
2304
|| vmargOptions.compareTo("-enableassertions") == 0 //$NON-NLS-1$
2305
|| vmargOptions.compareTo("-da") == 0 //$NON-NLS-1$
2306
|| vmargOptions.compareTo("-disableassertions") == 0 //$NON-NLS-1$
2307
) {
2308
foundAssertionOptions = true;
2309
boolean def = vmargOptions.charAt(1) == 'e';
2310
if (vmargExtraInfo == null) {
2311
if (bootLoader) {
2312
continue;
2313
}
2314
setDefaultAssertionStatusImpl(def);
2315
} else {
2316
String str = vmargExtraInfo;
2317
int len = str.length();
2318
if ( len > 3 && str.charAt(len-1) == '.' &&
2319
str.charAt(len-2) == '.' && str.charAt(len-3) == '.') {
2320
str = str.substring(0,len-3);
2321
setPackageAssertionStatusImpl(str, def);
2322
} else {
2323
setClassAssertionStatusImpl(str, def);
2324
}
2325
}
2326
} else if ( vmargOptions.compareTo("-esa") == 0 //$NON-NLS-1$
2327
|| vmargOptions.compareTo("-enablesystemassertions") == 0 //$NON-NLS-1$
2328
|| vmargOptions.compareTo("-dsa") == 0 //$NON-NLS-1$
2329
|| vmargOptions.compareTo("-disablesystemassertions") == 0 //$NON-NLS-1$
2330
) {
2331
if (bootLoader) {
2332
boolean def = vmargOptions.charAt(1) == 'e';
2333
setDefaultAssertionStatusImpl(def);
2334
}
2335
}
2336
2337
}
2338
if (bootLoader && foundAssertionOptions) {
2339
// assertion options found, every classloader must check the options
2340
checkAssertionOptions = true;
2341
}
2342
}
2343
2344
/**
2345
* Constructs a new class from an array of bytes containing a
2346
* class definition in class file format and assigns the new
2347
* class to the specified protection domain.
2348
*
2349
* @param name java.lang.String
2350
* the name of the new class.
2351
* @param buffer
2352
* a memory image of a class file.
2353
* @param domain
2354
* the protection domain this class should
2355
* belong to.
2356
*
2357
* @return the newly defined Class
2358
*
2359
* @throws ClassFormatError when the bytes are invalid
2360
*
2361
* @since 1.5
2362
*/
2363
protected final Class<?> defineClass(String name, java.nio.ByteBuffer buffer, ProtectionDomain domain) throws ClassFormatError {
2364
int position = buffer.position();
2365
int size = buffer.limit() - position;
2366
if (buffer.hasArray())
2367
return defineClass(name, buffer.array(), position, size, domain);
2368
2369
byte[] bytes = new byte[size];
2370
buffer.get(bytes);
2371
return defineClass(name, bytes, 0, size, domain);
2372
}
2373
2374
/**
2375
* Check if all the certs in one array are present in the other array
2376
* @param pcerts java.security.cert.Certificate[]
2377
* @param certs java.security.cert.Certificate[]
2378
* @return true when all the certs in one array are present in the other array
2379
* false otherwise
2380
*/
2381
private boolean compareCerts(java.security.cert.Certificate[] pcerts,
2382
java.security.cert.Certificate[] certs) {
2383
/*[PR CMVC 157478] compareCerts function missing in java.lang.ClassLoader class */
2384
if (pcerts == null) {
2385
pcerts = emptyCertificates;
2386
}
2387
if (certs == null) {
2388
certs = emptyCertificates;
2389
}
2390
if (pcerts == certs) {
2391
return true;
2392
} else if (pcerts.length != certs.length) {
2393
return false;
2394
}
2395
2396
boolean foundMatch = true;
2397
test: for(int i=0; i<pcerts.length; i++) {
2398
if (pcerts[i] == certs[i]) continue;
2399
if (pcerts[i].equals(certs[i])) continue;
2400
for(int j=0; j<certs.length; j++) {
2401
if (j == i) continue;
2402
if (pcerts[i] == certs[j]) continue test;
2403
if (pcerts[i].equals(certs[j])) continue test;
2404
}
2405
foundMatch = false;
2406
break;
2407
}
2408
return foundMatch;
2409
}
2410
2411
//prevent subclasses from becoming Cloneable
2412
@Override
2413
protected Object clone() throws CloneNotSupportedException {
2414
throw new CloneNotSupportedException();
2415
}
2416
2417
/**
2418
* Returns a {@code java.util.Map} from method descriptor string to the equivalent {@code MethodType} as generated by {@code MethodType.fromMethodDescriptorString}.
2419
* @return A {@code java.util.Map} from method descriptor string to the equivalent {@code MethodType}.
2420
*/
2421
Map<String, java.lang.invoke.MethodType> getMethodTypeCache() {
2422
if (null == methodTypeFromMethodDescriptorStringCache) {
2423
methodTypeFromMethodDescriptorStringCache = new java.util.concurrent.ConcurrentHashMap<>(16, 0.75f, 8);
2424
}
2425
return methodTypeFromMethodDescriptorStringCache;
2426
}
2427
2428
/*[IF Sidecar19-SE]*/
2429
ServicesCatalog createOrGetServicesCatalog() {
2430
if (null == this.servicesCatalog) {
2431
this.servicesCatalog = ServicesCatalog.create();
2432
}
2433
return this.servicesCatalog;
2434
}
2435
2436
ServicesCatalog getServicesCatalog() {
2437
return this.servicesCatalog;
2438
}
2439
2440
/*[ENDIF] Sidecar19-SE*/
2441
2442
/*[IF Sidecar19-SE]*/
2443
/**
2444
* Answers an URL which can be used to access the resource
2445
* described by resName, using the class loader's resource lookup
2446
* algorithm. By default, return null, unless moduleName is null,
2447
* in which case return findResource(resName).
2448
* This should be implemented by a ClassLoader.
2449
*
2450
* @return URL
2451
* the location of the resource.
2452
* @param moduleName String
2453
* the module name
2454
* @param resName String
2455
* the name of the resource to find.
2456
*
2457
* @throws IOException when an error occurs
2458
*/
2459
protected URL findResource(String moduleName, String resName) throws IOException {
2460
URL result = null;
2461
if (null == moduleName) {
2462
/* Handle the default case for subclasses which do not implement this method */
2463
result = findResource(resName);
2464
}
2465
return result;
2466
}
2467
2468
Package definePackage(String name, Module module) {
2469
Package pkg = null;
2470
if (name.isEmpty() && module.isNamed()) {
2471
throw new InternalError("Unnamed package in " + module); //$NON-NLS-1$
2472
}
2473
synchronized(packages) {
2474
NamedPackage np = packages.get(name);
2475
if ((null != np) && (np instanceof Package)) {
2476
pkg = (Package)np;
2477
} else {
2478
pkg = NamedPackage.toPackage(name, module);
2479
packages.put(name, pkg);
2480
}
2481
}
2482
2483
return pkg;
2484
}
2485
Stream<Package> packages() {
2486
return packages.values().stream().map(p->definePackage(p.packageName(), p.module()));
2487
}
2488
static ClassLoader getBuiltinAppClassLoader() {
2489
throw new Error("ClassLoader.getBuiltinAppClassLoader unimplemented"); //$NON-NLS-1$
2490
}
2491
static ClassLoader initSystemClassLoader() {
2492
throw new Error("ClassLoader.initSystemClassLoader unimplemented"); //$NON-NLS-1$
2493
}
2494
ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap() {
2495
if (null == classLoaderValueMap) {
2496
synchronized(lazyInitLock) {
2497
if (null == classLoaderValueMap) {
2498
classLoaderValueMap = new ConcurrentHashMap<>();
2499
}
2500
}
2501
}
2502
return classLoaderValueMap;
2503
}
2504
2505
/**
2506
* Answers a stream of URL which can be used to access the resources
2507
* described by name, using the class loader's resource lookup algorithm.
2508
*
2509
* @param name - the name of the resource to find
2510
2511
* @return a stream of the resources
2512
*
2513
* @throws NullPointerException when name is null
2514
*/
2515
public Stream<URL> resources(String name) {
2516
try {
2517
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(getResources(name).asIterator(), Spliterator.NONNULL | Spliterator.IMMUTABLE), false);
2518
} catch (IOException e) {
2519
throw new UncheckedIOException(e);
2520
}
2521
}
2522
2523
/**
2524
* Indicating if this class loader is registered as parallel capable or not
2525
*
2526
* @return true if this is registered as parallel capable, otherwise false is returned
2527
*/
2528
public final boolean isRegisteredAsParallelCapable() {
2529
return isParallelCapable;
2530
}
2531
2532
/*[ENDIF] Sidecar19-SE*/
2533
}
2534
2535