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