Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/test/functional/cmdLineTests/shareClassTests/utils/src/CustomCLs/CustomURLClassLoaderNonConfirming.java
6005 views
1
/*******************************************************************************
2
* Copyright (c) 2005, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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
21
*******************************************************************************/
22
package CustomCLs;
23
24
import java.io.ByteArrayOutputStream;
25
import java.io.File;
26
import java.io.FileInputStream;
27
import java.io.IOException;
28
import java.io.InputStream;
29
import java.net.JarURLConnection;
30
import java.net.MalformedURLException;
31
import java.net.URL;
32
import java.security.CodeSource;
33
import java.security.SecureClassLoader;
34
import java.util.Hashtable;
35
import java.util.jar.Attributes;
36
import java.util.jar.JarEntry;
37
import java.util.jar.JarFile;
38
import java.util.jar.Manifest;
39
import java.util.jar.Attributes.Name;
40
41
import com.ibm.oti.shared.CannotSetClasspathException;
42
import com.ibm.oti.shared.HelperAlreadyDefinedException;
43
import com.ibm.oti.shared.Shared;
44
import com.ibm.oti.shared.SharedClassHelperFactory;
45
import com.ibm.oti.shared.SharedClassTokenHelper;
46
import com.ibm.oti.shared.SharedClassURLClasspathHelper;
47
import com.ibm.oti.shared.SharedClassURLHelper;
48
49
/**
50
* @author Matthew Kilner
51
*/
52
public class CustomURLClassLoaderNonConfirming extends SecureClassLoader {
53
54
URL[] urls, orgUrls;
55
56
private Hashtable jarCache = new Hashtable(32);
57
int loaderType;
58
59
SharedClassURLClasspathHelper scHelper;
60
61
CustomLoaderMetaDataCache[] metaDataArray;
62
63
FoundAtIndex foundAtIndex = new FoundAtIndex();
64
65
public CustomURLClassLoaderNonConfirming(URL[] passedUrls, ClassLoader parent){
66
super(parent);
67
loaderType = ClassLoaderType.CACHEDURL.ord;
68
int urlLength = passedUrls.length;
69
urls = new URL[urlLength];
70
orgUrls = new URL[urlLength];
71
for (int i=0; i < urlLength; i++) {
72
try {
73
urls[i] = createSearchURL(passedUrls[i]);
74
} catch (MalformedURLException e) {}
75
orgUrls[i] = passedUrls[i];
76
}
77
metaDataArray = new CustomLoaderMetaDataCache[urls.length];
78
initMetaData();
79
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
80
if(schFactory != null){
81
try{
82
scHelper = schFactory.getURLClasspathHelper(this, passedUrls);
83
} catch (HelperAlreadyDefinedException e){
84
e.printStackTrace();
85
}
86
}
87
}
88
89
public CustomURLClassLoaderNonConfirming(URL[] passedUrls){
90
super();
91
loaderType = ClassLoaderType.CACHEDURL.ord;
92
int urlLength = passedUrls.length;
93
urls = new URL[urlLength];
94
orgUrls = new URL[urlLength];
95
for (int i=0; i < urlLength; i++) {
96
try {
97
urls[i] = createSearchURL(passedUrls[i]);
98
} catch (MalformedURLException e) {}
99
orgUrls[i] = passedUrls[i];
100
}
101
metaDataArray = new CustomLoaderMetaDataCache[urls.length];
102
initMetaData();
103
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
104
if(schFactory != null){
105
try{
106
scHelper = schFactory.getURLClasspathHelper(this, passedUrls);
107
} catch (HelperAlreadyDefinedException e){
108
e.printStackTrace();
109
}
110
}
111
}
112
113
public boolean getHelper(){
114
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
115
SharedClassURLClasspathHelper newHelper = null;
116
try{
117
newHelper = schFactory.getURLClasspathHelper(this, orgUrls);
118
} catch (HelperAlreadyDefinedException e){
119
return false;
120
}
121
122
if(newHelper.equals(scHelper)){
123
return true;
124
} else {
125
return false;
126
}
127
}
128
129
public void getHelper(URL[] urls)throws HelperAlreadyDefinedException {
130
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
131
SharedClassURLClasspathHelper newHelper = null;
132
newHelper = schFactory.getURLClasspathHelper(this, urls);
133
}
134
135
public void getURLHelper()throws Exception {
136
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
137
SharedClassURLHelper newHelper = null;
138
newHelper = schFactory.getURLHelper(this);
139
}
140
141
public void getTokenHelper()throws Exception {
142
SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();
143
SharedClassTokenHelper newHelper = null;
144
newHelper = schFactory.getTokenHelper(this);
145
}
146
147
public boolean duplicateStore(String name){
148
Class clazz = null;
149
try{
150
clazz = this.loadClass(name);
151
} catch (ClassNotFoundException e){
152
e.printStackTrace();
153
}
154
if (clazz != null){
155
int indexFoundAt = locateClass(name);
156
if(indexFoundAt != -1){
157
scHelper.storeSharedClass(clazz, indexFoundAt);
158
return true;
159
}
160
}
161
return false;
162
}
163
164
private static boolean isDirectory(URL url) {
165
String file = url.getFile();
166
return (file.length() > 0 && file.charAt(file.length()-1) == '/');
167
}
168
169
private URL createSearchURL(URL url) throws MalformedURLException {
170
if (url == null) return url;
171
String protocol = url.getProtocol();
172
173
if (isDirectory(url) || protocol.equals("jar")) {
174
return url;
175
} else {
176
return new URL("jar", "", -1, url.toString() + "!/");
177
}
178
}
179
180
private void initMetaData(){
181
for(int loopIndex = 0; loopIndex < metaDataArray.length; loopIndex++){
182
metaDataArray[loopIndex] = null;
183
}
184
}
185
186
private void addMetaDataEntry(){
187
CustomLoaderMetaDataCache[] newArray = new CustomLoaderMetaDataCache[(metaDataArray.length)];
188
System.arraycopy(metaDataArray,0,newArray,0,metaDataArray.length);
189
metaDataArray = newArray;
190
metaDataArray[(metaDataArray.length - 1)] = null;
191
}
192
193
public void addUrl(URL url){
194
URL searchURL = null;
195
try{
196
searchURL = createSearchURL(url);
197
} catch (Exception e){
198
e.printStackTrace();
199
}
200
URL[] newOrgUrls = new URL[(orgUrls.length)];
201
System.arraycopy(orgUrls,0,newOrgUrls,0,orgUrls.length);
202
orgUrls = newOrgUrls;
203
orgUrls[(orgUrls.length - 1)] = url;
204
URL[] newUrls = new URL[urls.length];
205
System.arraycopy(urls,0,newUrls,0,urls.length);
206
urls = newUrls;
207
urls[(urls.length - 1)] = searchURL;
208
scHelper.addClasspathEntry(url);
209
addMetaDataEntry();
210
}
211
212
public URL[] getURLS(){
213
return orgUrls;
214
}
215
216
private static byte[] getBytes(InputStream is, boolean readAvailable) throws IOException {
217
if (readAvailable) {
218
byte[] buf = new byte[is.available()];
219
is.read(buf, 0, buf.length);
220
is.close();
221
return buf;
222
}
223
byte[] buf = new byte[4096];
224
int size = is.available();
225
if (size < 1024) size = 1024;
226
ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
227
int count;
228
while ((count = is.read(buf)) > 0)
229
bos.write(buf, 0, count);
230
return bos.toByteArray();
231
}
232
233
private int locateClass(String className){
234
int classAtEntry = -1;
235
String name = className.replace('.','/').concat(".class");
236
for(int index = 0; index < urls.length; index ++){
237
URL currentUrl = urls[index];
238
if(currentUrl.getProtocol().equals("jar")){
239
JarEntry entry = null;
240
JarFile jf = (JarFile)jarCache.get(currentUrl);
241
if(jf == null){
242
/* First time we have encountered this jar.
243
* Lets cache its metaData.
244
*/
245
try{
246
URL jarFileUrl = ((JarURLConnection)currentUrl.openConnection()).getJarFileURL();
247
JarURLConnection jarUrlConnection = (JarURLConnection)new URL("jar", "", jarFileUrl.toExternalForm() + "!/").openConnection();
248
try{
249
jf = jarUrlConnection.getJarFile();
250
}catch(Exception e){
251
}
252
if(jf != null){
253
jarCache.put(currentUrl, jf);
254
}
255
} catch (Exception e){
256
e.printStackTrace();
257
}
258
if(jf != null){
259
Manifest manifest = null;
260
java.security.cert.Certificate[] certs = null;
261
URL csUrl = currentUrl;
262
CodeSource codeSource;
263
try{
264
manifest = jf.getManifest();
265
} catch(Exception e){
266
e.printStackTrace();
267
}
268
entry = jf.getJarEntry(name);
269
if(entry != null){
270
certs = entry.getCertificates();
271
}
272
codeSource = new CodeSource(csUrl, certs);
273
CustomLoaderMetaDataCache metaData = new CustomLoaderMetaDataCache();
274
metaData.manifest = manifest;
275
metaData.codeSource = codeSource;
276
metaDataArray[index] = metaData;
277
}
278
}
279
if(entry == null && jf != null){
280
entry = jf.getJarEntry(name);
281
}
282
if(entry != null){
283
/* We have the first match on the class path, return the current url index */
284
return index;
285
}
286
} else {
287
String filename = currentUrl.getFile();
288
String host = currentUrl.getHost();
289
if (host != null && host.length() > 0) {
290
filename = new StringBuffer(host.length() + filename.length() + name.length() + 2).
291
append("//").append(host).append(filename).append(name).toString();
292
} else {
293
filename = new StringBuffer(filename.length() + name.length()).
294
append(filename).append(name).toString();
295
}
296
File file = new File(filename);
297
// Don't throw exceptions for speed
298
if (file.exists()) {
299
if(metaDataArray[index] == null){
300
java.security.cert.Certificate[] certs = null;
301
CustomLoaderMetaDataCache metaData = new CustomLoaderMetaDataCache();
302
metaData.manifest = null;
303
metaData.codeSource = new CodeSource(currentUrl, certs);
304
metaDataArray[index] = metaData;
305
}
306
return index;
307
}
308
}
309
}
310
return classAtEntry;
311
}
312
313
private byte[] loadClassBytes(String className, int urlIndex){
314
byte[] bytes = null;
315
String name = className.replace('.','/').concat(".class");
316
URL classLocation = urls[urlIndex];
317
if(classLocation.getProtocol().equals("jar")){
318
JarFile jf = (JarFile)jarCache.get(classLocation);
319
JarEntry entry = jf.getJarEntry(name);
320
try{
321
InputStream stream = jf.getInputStream(entry);
322
bytes = getBytes(stream, true);
323
} catch (Exception e){
324
e.printStackTrace();
325
}
326
} else {
327
String filename = classLocation.getFile();
328
String host = classLocation.getHost();
329
if (host != null && host.length() > 0) {
330
filename = new StringBuffer(host.length() + filename.length() + name.length() + 2).
331
append("//").append(host).append(filename).append(name).toString();
332
} else {
333
filename = new StringBuffer(filename.length() + name.length()).
334
append(filename).append(name).toString();
335
}
336
File file = new File(filename);
337
// Don't throw exceptions for speed
338
if (file.exists()) {
339
try{
340
FileInputStream stream = new FileInputStream(file);
341
bytes = getBytes(stream, true);
342
} catch(Exception e){
343
e.printStackTrace();
344
}
345
}
346
}
347
return bytes;
348
}
349
350
public Class findClass(String name) throws ClassNotFoundException {
351
Class clazz = null;
352
if(scHelper != null){
353
byte[] classBytes = scHelper.findSharedClass(name, foundAtIndex);
354
if(classBytes != null){
355
if(metaDataArray[foundAtIndex.getIndex()] != null){
356
checkPackage(name, foundAtIndex.getIndex());
357
CustomLoaderMetaDataCache metadata = metaDataArray[foundAtIndex.getIndex()];
358
CodeSource codeSource = metadata.codeSource;
359
clazz = defineClass(name, classBytes, 0, classBytes.length, codeSource);
360
}
361
}
362
}
363
if(clazz == null) {
364
int indexFoundAt = locateClass(name);
365
if(indexFoundAt != -1){
366
try{
367
byte[] classBytes = loadClassBytes(name, indexFoundAt);
368
checkPackage(name, indexFoundAt);
369
CustomLoaderMetaDataCache metadata = metaDataArray[indexFoundAt];
370
CodeSource codeSource = metadata.codeSource;
371
clazz = defineClass(name, classBytes, 0, classBytes.length, codeSource);
372
if(clazz != null){
373
scHelper.storeSharedClass(clazz, indexFoundAt);
374
}
375
} catch (Exception e){
376
e.printStackTrace();
377
}
378
}
379
if(clazz == null){
380
throw new ClassNotFoundException(name);
381
}
382
}
383
return clazz;
384
}
385
386
private void checkPackage(String name, int urlIndex){
387
int index = name.lastIndexOf('.');
388
if(index != -1){
389
String packageString = name.substring(0, index);
390
Manifest manifest = metaDataArray[urlIndex].manifest;
391
CodeSource codeSource = metaDataArray[urlIndex].codeSource;
392
synchronized(this){
393
Package packageInst = getPackage(packageString);
394
if(packageInst == null){
395
if (manifest != null){
396
definePackage(packageString, manifest, codeSource.getLocation());
397
} else {
398
definePackage(packageString, null, null, null, null, null, null, null);
399
}
400
} else {
401
boolean exception = false;
402
if (manifest != null) {
403
String dirName = packageString.replace('.', '/') + "/";
404
if (isSealed(manifest, dirName))
405
exception = !packageInst.isSealed(codeSource.getLocation());
406
} else
407
exception = packageInst.isSealed();
408
if (exception)
409
throw new SecurityException(com.ibm.oti.util.Msg.getString("Package exception"));
410
}
411
}
412
}
413
}
414
415
private boolean isSealed(Manifest manifest, String dirName) {
416
Attributes mainAttributes = manifest.getMainAttributes();
417
String value = mainAttributes.getValue(Attributes.Name.SEALED);
418
boolean sealed = value != null &&
419
value.toLowerCase().equals ("true");
420
Attributes attributes = manifest.getAttributes(dirName);
421
if (attributes != null) {
422
value = attributes.getValue(Attributes.Name.SEALED);
423
if (value != null)
424
sealed = value.toLowerCase().equals("true");
425
}
426
return sealed;
427
}
428
429
protected Package definePackage(String name, Manifest man, URL url) throws IllegalArgumentException {
430
String path = name.replace('.','/').concat("/");
431
String[] attrs = new String[7];
432
URL sealedAtURL = null;
433
434
Attributes attr = man.getAttributes(path);
435
Attributes mainAttr = man.getMainAttributes();
436
437
if(attr != null){
438
attrs[0] = attr.getValue(Name.SPECIFICATION_TITLE);
439
attrs[1] = attr.getValue(Name.SPECIFICATION_VERSION);
440
attrs[2] = attr.getValue(Name.SPECIFICATION_VENDOR);
441
attrs[3] = attr.getValue(Name.IMPLEMENTATION_TITLE);
442
attrs[4] = attr.getValue(Name.IMPLEMENTATION_VERSION);
443
attrs[5] = attr.getValue(Name.IMPLEMENTATION_VENDOR);
444
attrs[6] = attr.getValue(Name.SEALED);
445
}
446
447
if(mainAttr != null){
448
if (attrs[0] == null) {
449
attrs[0] = mainAttr.getValue(Name.SPECIFICATION_TITLE);
450
}
451
if (attrs[1] == null) {
452
attrs[1] = mainAttr.getValue(Name.SPECIFICATION_VERSION);
453
}
454
if (attrs[2] == null) {
455
attrs[2] = mainAttr.getValue(Name.SPECIFICATION_VENDOR);
456
}
457
if (attrs[3] == null) {
458
attrs[3] = mainAttr.getValue(Name.IMPLEMENTATION_TITLE);
459
}
460
if (attrs[4] == null) {
461
attrs[4] = mainAttr.getValue(Name.IMPLEMENTATION_VERSION);
462
}
463
if (attrs[5] == null) {
464
attrs[5] = mainAttr.getValue(Name.IMPLEMENTATION_VENDOR);
465
}
466
if (attrs[6] == null) {
467
attrs[6] = mainAttr.getValue(Name.SEALED);
468
}
469
}
470
if ("true".equalsIgnoreCase(attrs[6])){
471
sealedAtURL = url;
472
}
473
return definePackage(name, attrs[0], attrs[1], attrs[2], attrs[3], attrs[4], attrs[5], sealedAtURL);
474
}
475
476
public boolean isClassInSharedCache(String className){
477
byte[] sharedClass = null;
478
if (scHelper!=null) {
479
sharedClass = scHelper.findSharedClass(className, foundAtIndex);
480
if (sharedClass !=null){
481
return true;
482
} else {
483
return false;
484
}
485
}
486
return false;
487
}
488
489
public Class getClassFromCache(String name){
490
Class clazz = null;
491
byte[] classBytes = scHelper.findSharedClass(name, foundAtIndex);
492
if(classBytes != null){
493
CodeSource cs = null;
494
clazz = defineClass(name, classBytes, 0, classBytes.length, cs);
495
}
496
return clazz;
497
}
498
499
public void confirmAllEntries(){
500
scHelper.confirmAllEntries();
501
}
502
503
public boolean changeClassPath(URL[] newUrls){
504
boolean changed = true;
505
int urlLength = newUrls.length;
506
urls = new URL[urlLength];
507
orgUrls = new URL[urlLength];
508
for (int i=0; i < urlLength; i++) {
509
try {
510
urls[i] = createSearchURL(newUrls[i]);
511
} catch (MalformedURLException e) {}
512
orgUrls[i] = newUrls[i];
513
}
514
metaDataArray = new CustomLoaderMetaDataCache[urls.length];
515
initMetaData();
516
try{
517
scHelper.setClasspath(newUrls);
518
} catch (CannotSetClasspathException e){
519
changed = false;
520
}
521
return changed;
522
}
523
524
public static class FoundAtIndex implements SharedClassURLClasspathHelper.IndexHolder {
525
526
int indexFoundAt = -1;
527
528
public void setIndex(int index) {
529
indexFoundAt = index;
530
}
531
532
public int getIndex(){
533
return indexFoundAt;
534
}
535
536
public void reset(){
537
indexFoundAt = -1;
538
}
539
540
}
541
}
542
543