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