Path: blob/master/test/functional/cmdLineTests/shareClassTests/utils/src/CustomCLs/CustomURLLoader.java
6005 views
/*******************************************************************************1* Copyright (c) 2005, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/21package CustomCLs;2223import java.io.ByteArrayOutputStream;24import java.io.File;25import java.io.FileInputStream;26import java.io.IOException;27import java.io.InputStream;28import java.net.JarURLConnection;29import java.net.MalformedURLException;30import java.net.URL;31import java.security.CodeSource;32import java.security.SecureClassLoader;33import java.util.Hashtable;34import java.util.jar.Attributes;35import java.util.jar.JarEntry;36import java.util.jar.JarFile;37import java.util.jar.Manifest;38import java.util.jar.Attributes.Name;3940import com.ibm.oti.shared.HelperAlreadyDefinedException;41import com.ibm.oti.shared.Shared;42import com.ibm.oti.shared.SharedClassHelperFactory;43import com.ibm.oti.shared.SharedClassTokenHelper;44import com.ibm.oti.shared.SharedClassURLClasspathHelper;45import com.ibm.oti.shared.SharedClassURLHelper;4647/**48* @author Matthew Kilner49*/50public class CustomURLLoader extends SecureClassLoader {5152URL[] urls, orgUrls, searchUrls;53URL url;5455private Hashtable jarCache = new Hashtable(32);56int loaderType;5758SharedClassURLHelper scHelper;5960CustomLoaderMetaDataCache[] metaDataArray;6162public CustomURLLoader(URL[] passedUrls, ClassLoader parent){63super(parent);64loaderType = ClassLoaderType.CACHEDURL.ord;65int urlLength = passedUrls.length;66searchUrls = new URL[urlLength];67urls = new URL[1];68orgUrls = new URL[urlLength];69for (int i=0; i < urlLength; i++) {70try {71searchUrls[i] = createSearchURL(passedUrls[i]);72} catch (MalformedURLException e) {}73orgUrls[i] = passedUrls[i];74}75metaDataArray = new CustomLoaderMetaDataCache[searchUrls.length];76initMetaData();77SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();78if(schFactory != null){79try{80scHelper = schFactory.getURLHelper(this);81} catch (Exception e){82e.printStackTrace();83}84}85}8687public CustomURLLoader(URL[] passedUrls){88super();89loaderType = ClassLoaderType.CACHEDURL.ord;90int urlLength = passedUrls.length;91searchUrls = new URL[urlLength];92urls = new URL[1];93orgUrls = new URL[urlLength];94for (int i=0; i < urlLength; i++) {95try {96searchUrls[i] = createSearchURL(passedUrls[i]);97} catch (MalformedURLException e) {}98orgUrls[i] = passedUrls[i];99}100metaDataArray = new CustomLoaderMetaDataCache[searchUrls.length];101initMetaData();102SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();103if(schFactory != null){104try{105scHelper = schFactory.getURLHelper(this);106} catch (Exception e){107e.printStackTrace();108}109}110}111112public void loadClassFrom(String name, int index){113urls[0] = searchUrls[index];114url = orgUrls[index];115try{116if (this.loadClass(name)==null)117{118System.out.println("CustomeURLLoader::loadClassFrom returned null.");119}120} catch(ClassNotFoundException e){121e.printStackTrace();122}123}124125public void loadClassNullStore(String name){126urls[0] = searchUrls[0];127int indexFoundAt = locateClass(name);128try{129byte[] classBytes = loadClassBytes(name, indexFoundAt);130checkPackage(name, indexFoundAt);131CustomLoaderMetaDataCache metadata = metaDataArray[indexFoundAt];132CodeSource codeSource = metadata.codeSource;133Class clazz = defineClass(name, classBytes, 0, classBytes.length, codeSource);134if(clazz != null){135scHelper.storeSharedClass(null, clazz);136}137} catch (Exception e){138e.printStackTrace();139}140}141142public boolean getHelper(){143SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();144SharedClassURLHelper newHelper = null;145try{146newHelper = schFactory.getURLHelper(this);147} catch (Exception e){148return false;149}150151if(newHelper.equals(scHelper)){152return true;153} else {154return false;155}156}157158public void getURLClasspathHelper()throws HelperAlreadyDefinedException {159SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();160SharedClassURLClasspathHelper newHelper = null;161newHelper = schFactory.getURLClasspathHelper(this, urls);162}163164public void getTokenHelper()throws Exception {165SharedClassHelperFactory schFactory = Shared.getSharedClassHelperFactory();166SharedClassTokenHelper newHelper = null;167newHelper = schFactory.getTokenHelper(this);168}169170public boolean duplicateStore(String name){171Class clazz = null;172try{173clazz = this.loadClass(name);174} catch (ClassNotFoundException e){175e.printStackTrace();176}177if (clazz != null){178int indexFoundAt = locateClass(name);179if(indexFoundAt != -1){180scHelper.storeSharedClass(urls[indexFoundAt], clazz);181return true;182}183}184return false;185}186187private void initMetaData(){188for(int loopIndex = 0; loopIndex < metaDataArray.length; loopIndex++){189metaDataArray[loopIndex] = null;190}191}192193private URL createSearchURL(URL url) throws MalformedURLException {194if (url == null) return url;195String protocol = url.getProtocol();196197if (isDirectory(url) || protocol.equals("jar")) {198return url;199} else {200return new URL("jar", "", -1, url.toString() + "!/");201}202}203204private static boolean isDirectory(URL url) {205String file = url.getFile();206return (file.length() > 0 && file.charAt(file.length()-1) == '/');207}208209public Class findClass(String name) throws ClassNotFoundException {210Class clazz = null;211int indexFoundAt = locateClass(name);212if(scHelper != null){213byte[] classBytes = scHelper.findSharedClass(url, name);214if(classBytes != null){215if(metaDataArray[indexFoundAt] != null){216checkPackage(name, indexFoundAt);217CustomLoaderMetaDataCache metadata = metaDataArray[indexFoundAt];218CodeSource codeSource = metadata.codeSource;219clazz = defineClass(name, classBytes, 0, classBytes.length, codeSource);220}221}222}223if(clazz == null) {224if(indexFoundAt != -1){225try{226byte[] classBytes = loadClassBytes(name, indexFoundAt);227checkPackage(name, indexFoundAt);228CustomLoaderMetaDataCache metadata = metaDataArray[indexFoundAt];229CodeSource codeSource = metadata.codeSource;230clazz = defineClass(name, classBytes, 0, classBytes.length, codeSource);231if(clazz != null){232scHelper.storeSharedClass(url, clazz);233}234} catch (Exception e){235e.printStackTrace();236}237}238if(clazz == null){239throw new ClassNotFoundException(name);240}241}242return clazz;243}244245private void checkPackage(String name, int urlIndex){246int index = name.lastIndexOf('.');247if(index != -1){248String packageString = name.substring(0, index);249Manifest manifest = metaDataArray[urlIndex].manifest;250CodeSource codeSource = metaDataArray[urlIndex].codeSource;251synchronized(this){252Package packageInst = getPackage(packageString);253if(packageInst == null){254if (manifest != null){255definePackage(packageString, manifest, codeSource.getLocation());256} else {257definePackage(packageString, null, null, null, null, null, null, null);258}259} else {260boolean exception = false;261if (manifest != null) {262String dirName = packageString.replace('.', '/') + "/";263if (isSealed(manifest, dirName))264exception = !packageInst.isSealed(codeSource.getLocation());265} else266exception = packageInst.isSealed();267if (exception)268throw new SecurityException(com.ibm.oti.util.Msg.getString("Package exception"));269}270}271}272}273274private static byte[] getBytes(InputStream is, boolean readAvailable) throws IOException {275if (readAvailable) {276byte[] buf = new byte[is.available()];277is.read(buf, 0, buf.length);278is.close();279return buf;280}281byte[] buf = new byte[4096];282int size = is.available();283if (size < 1024) size = 1024;284ByteArrayOutputStream bos = new ByteArrayOutputStream(size);285int count;286while ((count = is.read(buf)) > 0)287bos.write(buf, 0, count);288return bos.toByteArray();289}290291private byte[] loadClassBytes(String className, int urlIndex){292byte[] bytes = null;293String name = className.replace('.','/').concat(".class");294URL classLocation = urls[urlIndex];295if(classLocation.getProtocol().equals("jar")){296JarFile jf = (JarFile)jarCache.get(classLocation);297JarEntry entry = jf.getJarEntry(name);298try{299InputStream stream = jf.getInputStream(entry);300bytes = getBytes(stream, true);301} catch (Exception e){302e.printStackTrace();303}304} else {305String filename = classLocation.getFile();306String host = classLocation.getHost();307if (host != null && host.length() > 0) {308filename = new StringBuffer(host.length() + filename.length() + name.length() + 2).309append("//").append(host).append(filename).append(name).toString();310} else {311filename = new StringBuffer(filename.length() + name.length()).312append(filename).append(name).toString();313}314File file = new File(filename);315// Don't throw exceptions for speed316if (file.exists()) {317try{318FileInputStream stream = new FileInputStream(file);319bytes = getBytes(stream, true);320} catch(Exception e){321e.printStackTrace();322}323}324}325return bytes;326}327328private int locateClass(String className){329int classAtEntry = -1;330String name = className.replace('.','/').concat(".class");331for(int index = 0; index < urls.length; index ++){332URL currentUrl = urls[index];333if(currentUrl.getProtocol().equals("jar")){334JarEntry entry = null;335JarFile jf = (JarFile)jarCache.get(currentUrl);336if(jf == null){337/* First time we have encountered this jar.338* Lets cache its metaData.339*/340try{341URL jarFileUrl = ((JarURLConnection)currentUrl.openConnection()).getJarFileURL();342JarURLConnection jarUrlConnection = (JarURLConnection)new URL("jar", "", jarFileUrl.toExternalForm() + "!/").openConnection();343try{344jf = jarUrlConnection.getJarFile();345}catch(Exception e){346}347if(jf != null){348jarCache.put(currentUrl, jf);349}350} catch (Exception e){351e.printStackTrace();352}353if(jf != null){354Manifest manifest = null;355java.security.cert.Certificate[] certs = null;356URL csUrl = currentUrl;357CodeSource codeSource;358try{359manifest = jf.getManifest();360} catch(Exception e){361e.printStackTrace();362}363entry = jf.getJarEntry(name);364if(entry != null){365certs = entry.getCertificates();366}367codeSource = new CodeSource(csUrl, certs);368CustomLoaderMetaDataCache metaData = new CustomLoaderMetaDataCache();369metaData.manifest = manifest;370metaData.codeSource = codeSource;371metaDataArray[index] = metaData;372}373}374if(entry == null && jf != null){375entry = jf.getJarEntry(name);376}377if(entry != null){378/* We have the first match on the class path, return the current url index */379return index;380}381} else {382String filename = currentUrl.getFile();383String host = currentUrl.getHost();384if (host != null && host.length() > 0) {385filename = new StringBuffer(host.length() + filename.length() + name.length() + 2).386append("//").append(host).append(filename).append(name).toString();387} else {388filename = new StringBuffer(filename.length() + name.length()).389append(filename).append(name).toString();390}391File file = new File(filename);392// Don't throw exceptions for speed393if (file.exists()) {394if(metaDataArray[index] == null){395java.security.cert.Certificate[] certs = null;396CustomLoaderMetaDataCache metaData = new CustomLoaderMetaDataCache();397metaData.manifest = null;398metaData.codeSource = new CodeSource(currentUrl, certs);399metaDataArray[index] = metaData;400}401return index;402}403}404}405return classAtEntry;406}407408private boolean isSealed(Manifest manifest, String dirName) {409Attributes mainAttributes = manifest.getMainAttributes();410String value = mainAttributes.getValue(Attributes.Name.SEALED);411boolean sealed = value != null &&412value.toLowerCase().equals ("true");413Attributes attributes = manifest.getAttributes(dirName);414if (attributes != null) {415value = attributes.getValue(Attributes.Name.SEALED);416if (value != null)417sealed = value.toLowerCase().equals("true");418}419return sealed;420}421422protected Package definePackage(String name, Manifest man, URL url) throws IllegalArgumentException {423String path = name.replace('.','/').concat("/");424String[] attrs = new String[7];425URL sealedAtURL = null;426427Attributes attr = man.getAttributes(path);428Attributes mainAttr = man.getMainAttributes();429430if(attr != null){431attrs[0] = attr.getValue(Name.SPECIFICATION_TITLE);432attrs[1] = attr.getValue(Name.SPECIFICATION_VERSION);433attrs[2] = attr.getValue(Name.SPECIFICATION_VENDOR);434attrs[3] = attr.getValue(Name.IMPLEMENTATION_TITLE);435attrs[4] = attr.getValue(Name.IMPLEMENTATION_VERSION);436attrs[5] = attr.getValue(Name.IMPLEMENTATION_VENDOR);437attrs[6] = attr.getValue(Name.SEALED);438}439440if(mainAttr != null){441if (attrs[0] == null) {442attrs[0] = mainAttr.getValue(Name.SPECIFICATION_TITLE);443}444if (attrs[1] == null) {445attrs[1] = mainAttr.getValue(Name.SPECIFICATION_VERSION);446}447if (attrs[2] == null) {448attrs[2] = mainAttr.getValue(Name.SPECIFICATION_VENDOR);449}450if (attrs[3] == null) {451attrs[3] = mainAttr.getValue(Name.IMPLEMENTATION_TITLE);452}453if (attrs[4] == null) {454attrs[4] = mainAttr.getValue(Name.IMPLEMENTATION_VERSION);455}456if (attrs[5] == null) {457attrs[5] = mainAttr.getValue(Name.IMPLEMENTATION_VENDOR);458}459if (attrs[6] == null) {460attrs[6] = mainAttr.getValue(Name.SEALED);461}462}463if ("true".equalsIgnoreCase(attrs[6])){464sealedAtURL = url;465}466return definePackage(name, attrs[0], attrs[1], attrs[2], attrs[3], attrs[4], attrs[5], sealedAtURL);467}468469public boolean isClassInSharedCache(int index, String className){470URL url = orgUrls[index];471byte[] sharedClass = null;472if (scHelper!=null) {473sharedClass = scHelper.findSharedClass(url, className);474if (sharedClass !=null){475return true;476} else {477return false;478}479}480System.out.println("CustomeURLLoader::isClassInSharedCache scHelper is null.");481return false;482}483484public boolean isClassInSharedCacheNullFind(String className){485byte[] sharedClass = null;486if (scHelper!=null) {487sharedClass = scHelper.findSharedClass(null, className);488if (sharedClass !=null){489return true;490} else {491return false;492}493}494return false;495}496}497498499