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