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