private Class<?> makeClass(String className, JarFile file, JarEntry entry, URL jarLocation) { try { definePackage(className, file); byte[] jeBytes = getJarEntryBytes(file, entry); if (jeBytes == null) { System.out.println( "Could not get bytes for entry " + entry.getName() + " in jar" + file.getName()); return null; } else { // System.out.println("Loading class " + className + " from " + entry.getName() + " in " + // file.getName()); return defineClass( className, jeBytes, 0, jeBytes.length, jarLocation != null ? getProtectionDomain(jarLocation) : pd); } } catch (Throwable t) { System.out.println( "Error reading class file " + entry.getName() + " in jar" + file.getName() + ": " + t.toString()); return null; } }
/** Check the certificates with the ones in the jar file (all must match). */ private static final void validateCertificate( final Certificate[] rootCerts, final JarFile jar, final JarEntry entry, final byte[] buf) throws IOException, SecurityException { if (DEBUG) { System.err.println("JarUtil: validate JarEntry : " + entry.getName()); } // API states that we must read all of the data from the entry's // InputStream in order to be able to get its certificates final InputStream is = jar.getInputStream(entry); try { while (is.read(buf) > 0) {} } finally { is.close(); } // Get the certificates for the JAR entry final Certificate[] nativeCerts = entry.getCertificates(); if (nativeCerts == null || nativeCerts.length == 0) { throw new SecurityException("no certificate for " + entry.getName() + " in " + jar.getName()); } if (!SecurityUtil.equals(rootCerts, nativeCerts)) { throw new SecurityException( "certificates not equal for " + entry.getName() + " in " + jar.getName()); } }
/* * Check for all declared required extensions in the jar file * manifest. */ protected boolean checkExtensions(JarFile jar) throws ExtensionInstallationException { Manifest man; try { man = jar.getManifest(); } catch (IOException e) { return false; } if (man == null) { // The applet does not define a manifest file, so // we just assume all dependencies are satisfied. return true; } boolean result = true; Attributes attr = man.getMainAttributes(); if (attr != null) { // Let's get the list of declared dependencies String value = attr.getValue(Name.EXTENSION_LIST); if (value != null) { StringTokenizer st = new StringTokenizer(value); // Iterate over all declared dependencies while (st.hasMoreTokens()) { String extensionName = st.nextToken(); debug("The file " + jar.getName() + " appears to depend on " + extensionName); // Sanity Check String extName = extensionName + "-" + Name.EXTENSION_NAME.toString(); if (attr.getValue(extName) == null) { debug( "The jar file " + jar.getName() + " appers to depend on " + extensionName + " but does not define the " + extName + " attribute in its manifest "); } else { if (!checkExtension(extensionName, attr)) { debug("Failed installing " + extensionName); result = false; } } } } else { debug("No dependencies for " + jar.getName()); } } return result; }
public void addJarFile(JarFile jf, URL jarLocation) { jarFileList.add(jf); jarLocationByJarName.put(jf.getName(), jarLocation); String jfName = jf.getName(); Enumeration<JarEntry> jeEnum = jf.entries(); while (jeEnum.hasMoreElements()) { JarEntry je = jeEnum.nextElement(); if (je.isDirectory()) continue; String jeName = je.getName(); if (!jeName.endsWith(".class")) continue; String className = jeName.substring(0, jeName.length() - 6).replace('/', '.'); if (classCache.containsKey(className)) { System.out.println("Ignoring duplicate class " + className + " in jar " + jfName); continue; } if (trackKnown) knownClassJarEntries.put(className, new JarEntryInfo(je, jf, jarLocation)); /* NOTE: can't do this as classes are defined out of order, end up with NoClassDefFoundError for dependencies: Class<?> cls = makeClass(className, jf, je); if (cls != null) classCache.put(className, cls); */ if (checkJars) { try { getParent().loadClass(className); System.out.println( "Class " + className + " in jar " + jfName + " already loaded from parent ClassLoader"); } catch (ClassNotFoundException e) { /* hoping class is not found! */ } if (jarByClass.containsKey(className)) { System.out.println( "Found class " + className + " in \njar " + jfName + ", already loaded from \njar " + jarByClass.get(className)); } else { jarByClass.put(className, jfName); } } } }
@Override protected synchronized Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { Class<?> c = null; try { try { ClassLoader cl = getParent(); c = cl.loadClass(className); if (c != null) return c; } catch (ClassNotFoundException e) { /* let the next one handle this */ } try { c = findJarClass(className); if (c != null) return c; } catch (Exception e) { System.out.println( "Error loading class [" + className + "] from jars in war file [" + outerFile.getName() + "]: " + e.toString()); e.printStackTrace(); } throw new ClassNotFoundException("Class [" + className + "] not found"); } finally { if (c != null && resolve) { resolveClass(c); } } }
/** * @param jarFileUri jar:file:/some/path/gluegen-rt.jar!/ * @return JarFile as named by Uri within the given ClassLoader * @throws IllegalArgumentException null arguments * @throws IOException if the Jar file could not been found * @throws URISyntaxException */ public static JarFile getJarFile(final Uri jarFileUri) throws IOException, IllegalArgumentException, URISyntaxException { if (null == jarFileUri) { throw new IllegalArgumentException("null jarFileUri"); } if (DEBUG) { System.err.println("getJarFile.0: " + jarFileUri.toString()); } final URL jarFileURL = jarFileUri.toURL(); if (DEBUG) { System.err.println("getJarFile.1: " + jarFileURL.toString()); } final URLConnection urlc = jarFileURL.openConnection(); if (urlc instanceof JarURLConnection) { final JarURLConnection jarConnection = (JarURLConnection) jarFileURL.openConnection(); final JarFile jarFile = jarConnection.getJarFile(); if (DEBUG) { System.err.println("getJarFile res: " + jarFile.getName()); } return jarFile; } if (DEBUG) { System.err.println("getJarFile res: NULL"); } return null; }
public File findContainingJar(URL resourceURL) throws IllegalArgumentException, URISyntaxException, MalformedURLException, IllegalAccessException, InvocationTargetException { File result = null; if (resourceURL != null) { /* *The URL will be similar to http://host:port/...path-in-server-namespace!resource-spec *Extract the part preceding the ! and ask the Java Web Start loader to *find the locally-cached JAR file corresponding to that part of the URL. */ URI resourceURI = resourceURL.toURI(); String ssp = resourceURI.getSchemeSpecificPart(); String jarOnlySSP = ssp.substring(0, ssp.indexOf('!')); URL jarOnlyURL = new URL(jarOnlySSP).toURI().toURL(); /* *Use introspection to invoke the method. This avoids complications *in building the app server under Java 1.5 in which the JNLPClassLoader *does not provide the getJarFile method. */ JarFile jarFile = (JarFile) getJarFileMethod.invoke(getJNLPClassLoader(), jarOnlyURL); if (jarFile == null) { throw new IllegalArgumentException(resourceURL.toExternalForm()); } result = new File(jarFile.getName()); } return result; }
public String getName() { String entryName = null; if (entry != null) { entryName = entry.getName(); if (entryName.endsWith("/")) { entryName = entryName.substring(0, entryName.length() - 1); } } // for equality we don't consider the path or version of a JAR file, // only its name, // since it is likely to be found in multiple places such as the maven // repository and // web-inf/lib. Also, it shouldn't be reimported just because there is a // new version if the content itself has not changed. File iofile = new File(file.getName()); String jarWithoutVersion; try { jarWithoutVersion = new VersionedJar(iofile).getJarWithoutVersion(); } catch (NotAJarException e) { jarWithoutVersion = iofile.getName(); } return jarWithoutVersion + "!" + (entryName != null ? entryName : "n/a"); }
/** @see java.lang.ClassLoader#findResources(java.lang.String) */ @Override public Enumeration<URL> findResources(String resourceName) throws IOException { String webInfResourceName = "WEB-INF/classes/" + resourceName; List<URL> urlList = new ArrayList<URL>(); int jarFileListSize = jarFileList.size(); for (int i = 0; i < jarFileListSize; i++) { JarFile jarFile = jarFileList.get(i); JarEntry jarEntry = jarFile.getJarEntry(resourceName); // to better support war format, look for the resourceName in the WEB-INF/classes directory if (loadWebInf && jarEntry == null) jarEntry = jarFile.getJarEntry(webInfResourceName); if (jarEntry != null) { try { String jarFileName = jarFile.getName(); if (jarFileName.contains("\\")) jarFileName = jarFileName.replace('\\', '/'); urlList.add(new URL("jar:file:" + jarFileName + "!/" + jarEntry)); } catch (MalformedURLException e) { System.out.println( "Error making URL for [" + resourceName + "] in jar [" + jarFile + "] in war file [" + outerFile + "]: " + e.toString()); } } } // add all resources found in parent loader too Enumeration<URL> superResources = super.findResources(resourceName); while (superResources.hasMoreElements()) urlList.add(superResources.nextElement()); return Collections.enumeration(urlList); }
private Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) { try { // We must read the stream for the JarEntry to retrieve // its certificates. InputStream is = new BufferedInputStream(jarFile.getInputStream(je)); while (is.read(readBuffer, 0, readBuffer.length) != -1) { // not using } is.close(); return je != null ? je.getCertificates() : null; } catch (IOException e) { Log.w(TAG, "Exception reading " + je.getName() + " in " + jarFile.getName(), e); } catch (RuntimeException e) { Log.w(TAG, "Exception reading " + je.getName() + " in " + jarFile.getName(), e); } return null; }
private Class<?> injectToBootstrapClassLoader(String className) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { if (injectedToRoot.compareAndSet(false, true)) { instrumentation.appendToBootstrapClassLoaderSearch(pluginJar); classPool.appendToBootstrapClassPath(pluginJar.getName()); } return Class.forName(className, false, null); }
private Class<?> injectToPlainClassLoader(ClassLoader classLoader, String className) throws NotFoundException, IllegalArgumentException, IOException, CannotCompileException, IllegalAccessException, InvocationTargetException { ClassPool pool = new ClassPool(); pool.appendClassPath(new LoaderClassPath(classLoader)); pool.appendClassPath(pluginJar.getName()); return injectToPlainClassLoader(pool, classLoader, className); }
private void index() throws IOException { Enumeration entries = _jar.entries(); _nameToEntryMap = new HashMap(); _crcToEntryMap = new HashMap(); _entries = new ArrayList(); if (_debug) { System.out.println("indexing: " + _jar.getName()); } if (entries != null) { while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); long crc = entry.getCrc(); Long crcL = new Long(crc); if (_debug) { System.out.println("\t" + entry.getName() + " CRC " + crc); } _nameToEntryMap.put(entry.getName(), entry); _entries.add(entry); // generate the CRC to entries map if (_crcToEntryMap.containsKey(crcL)) { // key exist, add the entry to the correcponding // linked list // get the linked list LinkedList ll = (LinkedList) _crcToEntryMap.get(crcL); // put in the new entry ll.add(entry); // put it back in the hash map _crcToEntryMap.put(crcL, ll); } else { // create a new entry in the hashmap for the new key // first create the linked list and put in the new // entry LinkedList ll = new LinkedList(); ll.add(entry); // create the new entry in the hashmap _crcToEntryMap.put(crcL, ll); } } } }
public static void addJar(JarFile jar) throws IOException { Manifest manifest = jar.getManifest(); String atList = manifest.getMainAttributes().getValue("FMLAT"); if (atList == null) return; for (String at : atList.split(" ")) { JarEntry jarEntry = jar.getJarEntry("META-INF/" + at); if (jarEntry != null) { embedded.put( String.format("%s!META-INF/%s", jar.getName(), at), new JarByteSource(jar, jarEntry).asCharSource(Charsets.UTF_8).read()); } } }
/** @see java.lang.ClassLoader#findResource(java.lang.String) */ @Override protected URL findResource(String resourceName) { if (resourceCache.containsKey(resourceName)) return resourceCache.get(resourceName); // try the runtime/classes directory for conf files and such String runtimePath = System.getProperty("moqui.runtime"); String fullPath = runtimePath + "/classes/" + resourceName; File resourceFile = new File(fullPath); if (resourceFile.exists()) try { return resourceFile.toURI().toURL(); } catch (MalformedURLException e) { System.out.println( "Error making URL for [" + resourceName + "] in runtime classes directory [" + runtimePath + "/classes/" + "]: " + e.toString()); } String webInfResourceName = "WEB-INF/classes/" + resourceName; int jarFileListSize = jarFileList.size(); for (int i = 0; i < jarFileListSize; i++) { JarFile jarFile = jarFileList.get(i); JarEntry jarEntry = jarFile.getJarEntry(resourceName); // to better support war format, look for the resourceName in the WEB-INF/classes directory if (loadWebInf && jarEntry == null) jarEntry = jarFile.getJarEntry(webInfResourceName); if (jarEntry != null) { try { String jarFileName = jarFile.getName(); if (jarFileName.contains("\\")) jarFileName = jarFileName.replace('\\', '/'); URL resourceUrl = new URL("jar:file:" + jarFileName + "!/" + jarEntry); resourceCache.put(resourceName, resourceUrl); return resourceUrl; } catch (MalformedURLException e) { System.out.println( "Error making URL for [" + resourceName + "] in jar [" + jarFile + "] in war file [" + outerFile + "]: " + e.toString()); } } } return super.findResource(resourceName); }
@Override public String toString() { String name = null; if (entry != null) { name = entry.getName(); if (name.endsWith("/")) { name = name.substring(0, name.length() - 1); } } return file.getName() + "!" + (name != null ? name : "n/a"); }
/** @see java.lang.ClassLoader#findResources(java.lang.String) */ @Override public Enumeration<URL> findResources(String resourceName) throws IOException { ArrayList<URL> cachedUrls = resourceAllCache.get(resourceName); if (cachedUrls != null) return Collections.enumeration(cachedUrls); ArrayList<URL> urlList = new ArrayList<>(); int classesDirectoryListSize = classesDirectoryList.size(); for (int i = 0; i < classesDirectoryListSize; i++) { File classesDir = classesDirectoryList.get(i); File testFile = new File(classesDir.getAbsolutePath() + "/" + resourceName); try { if (testFile.exists() && testFile.isFile()) urlList.add(testFile.toURI().toURL()); } catch (MalformedURLException e) { System.out.println( "Error making URL for [" + resourceName + "] in classes directory [" + classesDir + "]: " + e.toString()); } } int jarFileListSize = jarFileList.size(); for (int i = 0; i < jarFileListSize; i++) { JarFile jarFile = jarFileList.get(i); JarEntry jarEntry = jarFile.getJarEntry(resourceName); if (jarEntry != null) { try { String jarFileName = jarFile.getName(); if (jarFileName.contains("\\")) jarFileName = jarFileName.replace('\\', '/'); urlList.add(new URL("jar:file:" + jarFileName + "!/" + jarEntry)); } catch (MalformedURLException e) { System.out.println( "Error making URL for [" + resourceName + "] in jar [" + jarFile + "]: " + e.toString()); } } } // add all resources found in parent loader too Enumeration<URL> superResources = getParent().getResources(resourceName); while (superResources.hasMoreElements()) urlList.add(superResources.nextElement()); resourceAllCache.putIfAbsent(resourceName, urlList); // System.out.println("finding all resources with name " + resourceName + " got " + urlList); return Collections.enumeration(urlList); }
private JarFile[] getClassPathJars() throws IOException { Vector<JarFile> jars = new Vector<JarFile>(); String classPath = System.getProperty("java.class.path"); String pathSeparator = System.getProperty("path.separator"); StringTokenizer strTok = new StringTokenizer(classPath, pathSeparator); while (strTok.hasMoreTokens()) { String classPathEntry = strTok.nextToken(); File file = new File(classPathEntry); if (isJarFile(file)) { jars.add(new JarFile(file)); } } /* * If only one JAR was found assume that application was started using * "jar" option - look in JAR manifest's Class-Path entry for the rest * of the JARs */ if (jars.size() == 1) { JarFile jarFile = jars.get(0); Manifest manifest = jarFile.getManifest(); if (manifest != null) { Attributes attributes = manifest.getMainAttributes(); String jarClassPath = attributes.getValue("Class-Path"); if (jarClassPath != null) { strTok = new StringTokenizer(jarClassPath, " "); while (strTok.hasMoreTokens()) { String jarClassPathEntry = strTok.nextToken(); File file = new File(new File(jarFile.getName()).getParent(), jarClassPathEntry); if (isJarFile(file)) { jars.add(new JarFile(file)); } } } } } return jars.toArray(new JarFile[jars.size()]); }
public URLConnection openConnection(URL url) throws IOException { if (expectedUrl == null) { throw new IllegalStateException("expectedUrl was not set"); } // the caller copied the URL reusing a stream handler from a previous call if (!expectedUrl.equals(url)) { // the new url is supposed to be within our context, so it must have a jar protocol if (!url.getProtocol().equals("jar")) { throw new IllegalArgumentException("Unsupported protocol " + url.getProtocol()); } // split the path at "!/" into the file part and entry part String path = url.getPath(); String[] chunks = path.split("!/", 2); // if we only got only one chunk, it didn't contain the required "!/" delimiter if (chunks.length == 1) { throw new MalformedURLException("Url does not contain a '!' character: " + url); } String file = chunks[0]; String entryPath = chunks[1]; // this handler only supports jars on the local file system if (!file.startsWith("file:")) { // let the system handler deal with this return new URL(url.toExternalForm()).openConnection(); } file = file.substring("file:".length()); // again the new url is supposed to be within our context so it must reference the same jar // file if (!jarFile.getName().equals(file)) { // let the system handler deal with this return new URL(url.toExternalForm()).openConnection(); } // get the entry JarEntry newEntry = jarFile.getJarEntry(entryPath); if (newEntry == null) { throw new FileNotFoundException("Entry not found: " + url); } return new JarFileUrlConnection(url, jarFile, newEntry); } return new JarFileUrlConnection(url, jarFile, jarEntry); }
/* ------------------------------------------------------------ */ @Override protected synchronized void newConnection() throws IOException { super.newConnection(); _entry = null; _file = null; _jarFile = null; _list = null; int sep = _urlString.indexOf("!/"); _jarUrl = _urlString.substring(0, sep + 2); _path = _urlString.substring(sep + 2); if (_path.length() == 0) _path = null; _jarFile = _jarConnection.getJarFile(); _file = new File(_jarFile.getName()); }
private Class<?> findJarClass(String className) throws IOException, ClassFormatError, ClassNotFoundException { Class cachedClass = classCache.get(className); if (cachedClass != null) return cachedClass; if (rememberClassNotFound) { ClassNotFoundException cachedExc = notFoundCache.get(className); if (cachedExc != null) throw cachedExc; } Class<?> c = null; String classFileName = className.replace('.', '/').concat(".class"); int classesDirectoryListSize = classesDirectoryList.size(); for (int i = 0; i < classesDirectoryListSize; i++) { File classesDir = classesDirectoryList.get(i); File testFile = new File(classesDir.getAbsolutePath() + "/" + classFileName); if (testFile.exists() && testFile.isFile()) { c = makeClass(className, testFile); if (c != null) break; } } if (c == null) { int jarFileListSize = jarFileList.size(); for (int i = 0; i < jarFileListSize; i++) { JarFile jarFile = jarFileList.get(i); // System.out.println("Finding class file " + classFileName + " in jar file " + // jarFile.getName()); JarEntry jarEntry = jarFile.getJarEntry(classFileName); if (jarEntry != null) { c = makeClass(className, jarFile, jarEntry, jarLocationByJarName.get(jarFile.getName())); break; } } } // down here only cache if found if (c != null) { Class existingClass = classCache.putIfAbsent(className, c); if (existingClass != null) return existingClass; else return c; } else { return null; } }
private static Map<String, InputStream> findResourceInFile( File resourceFile, String fileNamePattern) throws IOException { Map<String, InputStream> result = new TreeMap<String, InputStream>(); if (resourceFile.canRead() && resourceFile.getAbsolutePath().endsWith(".jar")) { log.debug("jar file found: " + resourceFile.getAbsolutePath()); JarFile jarFile = new JarFile(resourceFile); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry singleEntry = entries.nextElement(); log.debug("jar entry: " + singleEntry.getName()); if (singleEntry.getName().matches(fileNamePattern)) { result.put( jarFile.getName() + "/" + singleEntry.getName(), jarFile.getInputStream(singleEntry)); } } } return result; }
private LameIndex index(JarFile jar) throws IOException, MojoExecutionException { String fileName = jar.getName(); int dotIndex = fileName.lastIndexOf('.'); if (dotIndex == -1) { throw new MojoExecutionException("cold not determine type of artifact: " + jar); } String extension = fileName.substring(dotIndex + 1); boolean changed = false; Index index = null; if (containsClasses(extension)) { if (!containsIndex(jar)) { index = buildIndex(jar); changed = true; } } List<LameSubDeploymentIndex> resultIndices; if (containsSubDeplyoments(extension)) { List<SubDeploymentIndex> subDeploymentIndexs = indexSubdeplyoments(extension, jar); if (!subDeploymentIndexs.isEmpty()) { resultIndices = new ArrayList<>(subDeploymentIndexs.size()); changed = true; for (SubDeploymentIndex each : subDeploymentIndexs) { Index subDeploymentIndex = each.index; String subDeploymentName = each.subDeployment.getName(); File subDepolyentFile; int subDeploymentDotIndex = subDeploymentName.lastIndexOf('.'); String subDeploymentExtension = subDeploymentName.substring(subDeploymentDotIndex + 1); if (containsSubDeplyoments(subDeploymentExtension)) { subDepolyentFile = each.file; } else { subDepolyentFile = null; } resultIndices.add( new LameSubDeploymentIndex(subDeploymentName, subDeploymentIndex, subDepolyentFile)); } } else { resultIndices = Collections.emptyList(); } } else { resultIndices = Collections.emptyList(); } return new LameIndex(index, changed, resultIndices); }
private void scan() throws InvalidPluginException { Enumeration<JarEntry> e = jarFile.entries(); while (e.hasMoreElements()) { JarEntry entry = e.nextElement(); if (skip(entry)) { continue; } ClassData def = new ClassData(); try { new ClassReader(read(entry)).accept(def, SKIP_ALL); } catch (IOException err) { throw new InvalidPluginException("Cannot auto-register", err); } catch (RuntimeException err) { PluginLoader.log.warn( String.format( "Plugin %s has invaild class file %s inside of %s", pluginName, entry.getName(), jarFile.getName()), err); continue; } if (def.exportedAsName != null) { if (def.isConcrete()) { export(def); } else { PluginLoader.log.warn( String.format( "Plugin %s tries to @Export(\"%s\") abstract class %s", pluginName, def.exportedAsName, def.className)); } } else if (def.listen) { if (def.isConcrete()) { listen(def); } else { PluginLoader.log.warn( String.format( "Plugin %s tries to @Listen abstract class %s", pluginName, def.className)); } } } }
/** * Validate the certificates for each native Lib in the jar file. Throws an IOException if any * certificate is not valid. * * <pre> * Certificate[] rootCerts = Something.class.getProtectionDomain(). * getCodeSource().getCertificates(); * </pre> */ public static final void validateCertificates( final Certificate[] rootCerts, final JarFile jarFile) throws IOException, SecurityException { if (DEBUG) { System.err.println("JarUtil: validateCertificates: " + jarFile.getName()); } if (rootCerts == null || rootCerts.length == 0) { throw new IllegalArgumentException("Null certificates passed"); } final byte[] buf = new byte[1024]; final Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { final JarEntry entry = entries.nextElement(); if (!entry.isDirectory() && !entry.getName().startsWith("META-INF/")) { // only validate non META-INF and non directories validateCertificate(rootCerts, jarFile, entry, buf); } } }
protected Class<?> findJarClass(String className) throws IOException, ClassFormatError { if (classCache.containsKey(className)) return classCache.get(className); Class<?> c = null; String classFileName = className.replace('.', '/') + ".class"; String webInfFileName = "WEB-INF/classes/" + classFileName; int jarFileListSize = jarFileList.size(); for (int i = 0; i < jarFileListSize; i++) { JarFile jarFile = jarFileList.get(i); // System.out.println("Finding Class [" + className + "] in jarFile [" + jarFile.getName() + // "]"); JarEntry jarEntry = jarFile.getJarEntry(classFileName); // to better support war format, look for the resourceName in the WEB-INF/classes directory if (loadWebInf && jarEntry == null) jarEntry = jarFile.getJarEntry(webInfFileName); if (jarEntry != null) { definePackage(className, jarFile); byte[] jeBytes = getJarEntryBytes(jarFile, jarEntry); if (jeBytes == null) { System.out.println( "Could not get bytes for [" + jarEntry.getName() + "] in [" + jarFile.getName() + "]"); continue; } // System.out.println("Class [" + classFileName + "] FOUND in jarFile [" + jarFile.getName() // + "], size is " + (jeBytes == null ? "null" : jeBytes.length)); c = defineClass(className, jeBytes, 0, jeBytes.length, pd); break; } } classCache.put(className, c); return c; }
public static void main(String[] args) throws IOException { // now grab the first arg and see if it is a known command String firstArg = args.length > 0 ? args[0] : ""; if (firstArg.contains("-help") || "-?".equals(firstArg)) { // setup the class loader MoquiStart moquiStartLoader = new MoquiStart(true); Thread.currentThread().setContextClassLoader(moquiStartLoader); Runtime.getRuntime() .addShutdownHook(new MoquiShutdown(null, null, moquiStartLoader.jarFileList)); initSystemProperties(moquiStartLoader, false); System.out.println("Internal Class Path Jars:"); for (JarFile jf : moquiStartLoader.jarFileList) { String fn = jf.getName(); System.out.println(fn.contains("moqui_temp") ? fn.substring(fn.indexOf("moqui_temp")) : fn); } System.out.println("------------------------------------------------"); System.out.println( "Current runtime directory (moqui.runtime): " + System.getProperty("moqui.runtime")); System.out.println( "Current configuration file (moqui.conf): " + System.getProperty("moqui.conf")); System.out.println( "To set these properties use something like: java -Dmoqui.conf=conf/MoquiStagingConf.xml -jar moqui.war ..."); System.out.println("------------------------------------------------"); System.out.println("Usage: java -jar moqui.war [command] [arguments]"); System.out.println("-help, -? ---- Help (this text)"); System.out.println("-load -------- Run data loader"); System.out.println( " -types=<type>[,<type>] ------- Data types to load (can be anything, common are: seed, seed-initial, demo, ...)"); System.out.println( " -components=<name>[,<name>] -- Component names to load for data types; if none specified loads from all"); System.out.println(" -location=<location> ---- Location of data file to load"); System.out.println( " -timeout=<seconds> ------ Transaction timeout for each file, defaults to 600 seconds (10 minutes)"); System.out.println( " -dummy-fks -------------- Use dummy foreign-keys to avoid referential integrity errors"); System.out.println( " -use-try-insert --------- Try insert and update on error instead of checking for record first"); System.out.println(" -tenantId=<tenantId> ---- ID for the Tenant to load the data into"); System.out.println( " If no -types or -location argument is used all known data files of all types will be loaded."); System.out.println("[default] ---- Run embedded Winstone server."); System.out.println( " See https://code.google.com/p/winstone/wiki/CmdLineOption for all argument details."); System.out.println(" Selected argument details:"); System.out.println( " --httpPort = set the http listening port. -1 to disable, Default is 8080"); System.out.println( " --httpListenAddress = set the http listening address. Default is all interfaces"); System.out.println( " --httpsPort = set the https listening port. -1 to disable, Default is disabled"); System.out.println( " --ajp13Port = set the ajp13 listening port. -1 to disable, Default is 8009"); System.out.println( " --controlPort = set the shutdown/control port. -1 to disable, Default disabled"); System.out.println(""); System.exit(0); } // make a list of arguments, remove the first one (the command) List<String> argList = new ArrayList<String>(Arrays.asList(args)); // now run the command if ("-load".equals(firstArg)) { MoquiStart moquiStartLoader = new MoquiStart(true); Thread.currentThread().setContextClassLoader(moquiStartLoader); Runtime.getRuntime() .addShutdownHook(new MoquiShutdown(null, null, moquiStartLoader.jarFileList)); initSystemProperties(moquiStartLoader, false); Map<String, String> argMap = new HashMap<String, String>(); for (String arg : argList) { if (arg.startsWith("-")) arg = arg.substring(1); if (arg.contains("=")) { argMap.put(arg.substring(0, arg.indexOf("=")), arg.substring(arg.indexOf("=") + 1)); } else { argMap.put(arg, ""); } } try { System.out.println("Loading data with args [" + argMap + "]"); Class<?> c = moquiStartLoader.loadClass("org.moqui.Moqui"); Method m = c.getMethod("loadData", new Class[] {Map.class}); m.invoke(null, argMap); } catch (Exception e) { System.out.println( "Error loading or running Moqui.loadData with args [" + argMap + "]: " + e.toString()); e.printStackTrace(); } System.exit(0); } // ===== Done trying specific commands, so load the embedded server // Get a start loader with loadWebInf=false since the container will load those we don't want to // here (would be on classpath twice) MoquiStart moquiStartLoader = new MoquiStart(false); Thread.currentThread().setContextClassLoader(moquiStartLoader); // NOTE: the MoquiShutdown hook is not set here because we want to get the winstone Launcher // object first, so done below... initSystemProperties(moquiStartLoader, true); Map<String, String> argMap = new HashMap<String, String>(); for (String arg : argList) { if (arg.startsWith("--")) arg = arg.substring(2); if (arg.contains("=")) { argMap.put(arg.substring(0, arg.indexOf("=")), arg.substring(arg.indexOf("=") + 1)); } else { argMap.put(arg, ""); } } try { argMap.put("warfile", moquiStartLoader.outerFile.getName()); System.out.println("Running Winstone embedded server with args [" + argMap + "]"); /* for old Winstone 0.9.10: Class<?> c = moquiStartLoader.loadClass("winstone.Launcher"); Method initLogger = c.getMethod("initLogger", new Class[] { Map.class }); Method shutdown = c.getMethod("shutdown"); // init the Winstone logger initLogger.invoke(null, argMap); // start Winstone with a new instance of the server Constructor wlc = c.getConstructor(new Class[] { Map.class }); Object winstone = wlc.newInstance(argMap); */ Class<?> c = moquiStartLoader.loadClass("net.winstone.Server"); Method start = c.getMethod("start"); // Method shutdown = c.getMethod("shutdown"); // start Winstone with a new instance of the server Constructor wlc = c.getConstructor(new Class[] {Map.class}); Object winstone = wlc.newInstance(argMap); start.invoke(winstone); // NOTE: winstone seems to have its own shutdown hook in the newer version, so using hook to // close files only: Thread shutdownHook = new MoquiShutdown(null, null, moquiStartLoader.jarFileList); shutdownHook.setDaemon(true); Runtime.getRuntime().addShutdownHook(shutdownHook); } catch (Exception e) { System.out.println( "Error loading or running Winstone embedded server with args [" + argMap + "]: " + e.toString()); e.printStackTrace(); } // now wait for break... }
/** * Constructor. * * @param parent class loader parent. */ public JarClassLoader(ClassLoader parent) { super(parent); initLogger(); hmClass = new HashMap<String, Class<?>>(); lstJarFile = new ArrayList<JarFileInfo>(); hsDeleteOnExit = new HashSet<File>(); // Prepare common for all protocols String sUrlTopJar = null; pd = getClass().getProtectionDomain(); CodeSource cs = pd.getCodeSource(); URL urlTopJar = cs.getLocation(); String protocol = urlTopJar.getProtocol(); // Work with different cases: JarFileInfo jarFileInfo = null; if ("http".equals(protocol) || "https".equals(protocol)) { // Protocol 'http' - application launched from WebStart / JNLP or as Java applet try { // Convert: // urlTopJar = "http://.../MyApp.jar" --> connection // sun.net.www.protocol.http.HttpURLConnection // to // urlTopJar = "jar:http://.../MyApp.jar!/" --> connection java.net.JarURLConnection urlTopJar = new URL("jar:" + urlTopJar + "!/"); JarURLConnection jarCon = (JarURLConnection) urlTopJar.openConnection(); JarFile jarFile = jarCon.getJarFile(); jarFileInfo = new JarFileInfo(jarFile, jarFile.getName(), null, null); logInfo(LogArea.JAR, "Loading from top JAR: '%s' PROTOCOL: '%s'", urlTopJar, protocol); } catch (Exception e) { // ClassCastException, IOException logError(LogArea.JAR, "Failure to load HTTP JAR: %s %s", urlTopJar, e.toString()); return; } } if ("file".equals(protocol)) { // Protocol 'file' - application launched from exploded dir or JAR // Decoding required for 'space char' in URL: // URL.getFile() returns "/C:/my%20dir/MyApp.jar" for "/C:/my dir/MyApp.jar" try { sUrlTopJar = URLDecoder.decode(urlTopJar.getFile(), "UTF-8"); } catch (UnsupportedEncodingException e) { logError(LogArea.JAR, "Failure to decode URL: %s %s", urlTopJar, e.toString()); return; } File fileJar = new File(sUrlTopJar); // Application is loaded from directory: if (fileJar.isDirectory()) { logInfo(LogArea.JAR, "Loading from exploded directory: %s", sUrlTopJar); return; // JarClassLoader completed its job } // Application is loaded from a JAR: try { // The call "new JarFile(fileJar)" might throw IOException jarFileInfo = new JarFileInfo(new JarFile(fileJar), fileJar.getName(), null, null); logInfo(LogArea.JAR, "Loading from top JAR: '%s' PROTOCOL: '%s'", sUrlTopJar, protocol); } catch (IOException e) { logError(LogArea.JAR, "Not a JAR: %s %s", sUrlTopJar, e.toString()); return; } } // FINALLY LOAD TOP JAR: try { if (jarFileInfo == null) { throw new IOException(String.format("Unknown protocol %s", protocol)); } loadJar(jarFileInfo); } catch (IOException e) { logError(LogArea.JAR, "Not valid URL: %s %s", urlTopJar, e.toString()); return; } checkShading(); Runtime.getRuntime() .addShutdownHook( new Thread() { public void run() { shutdown(); } }); } // JarClassLoader()
protected LoadServiceResource tryResourceFromJarURLWithLoadPath( String namePlusSuffix, String loadPathEntry) { LoadServiceResource foundResource = null; JarFile current = jarFiles.get(loadPathEntry); boolean isFileJarUrl = loadPathEntry.startsWith("file:") && loadPathEntry.indexOf("!/") != -1; String after = isFileJarUrl ? loadPathEntry.substring(loadPathEntry.indexOf("!/") + 2) + "/" : ""; String before = isFileJarUrl ? loadPathEntry.substring(0, loadPathEntry.indexOf("!/")) : loadPathEntry; if (null == current) { try { if (loadPathEntry.startsWith("jar:")) { current = new JarFile(loadPathEntry.substring(4)); } else if (loadPathEntry.endsWith(".jar")) { current = new JarFile(loadPathEntry); } else { current = new JarFile(loadPathEntry.substring(5, loadPathEntry.indexOf("!/"))); } jarFiles.put(loadPathEntry, current); } catch (ZipException ignored) { if (runtime.getInstanceConfig().isDebug()) { runtime .getErr() .println("ZipException trying to access " + loadPathEntry + ", stack trace follows:"); ignored.printStackTrace(runtime.getErr()); } } catch (FileNotFoundException ignored) { } catch (IOException e) { throw runtime.newIOErrorFromException(e); } } String canonicalEntry = after + namePlusSuffix; if (current != null) { debugLogTry("resourceFromJarURLWithLoadPath", current.getName() + "!/" + canonicalEntry); if (current.getJarEntry(canonicalEntry) != null) { try { if (loadPathEntry.endsWith(".jar")) { foundResource = new LoadServiceResource( new URL("jar:file:" + loadPathEntry + "!/" + canonicalEntry), "/" + namePlusSuffix); } else if (loadPathEntry.startsWith("file:")) { foundResource = new LoadServiceResource( new URL("jar:" + before + "!/" + canonicalEntry), loadPathEntry + "/" + namePlusSuffix); } else { foundResource = new LoadServiceResource( new URL("jar:file:" + loadPathEntry.substring(4) + "!/" + namePlusSuffix), loadPathEntry + namePlusSuffix); } debugLogFound(foundResource); } catch (MalformedURLException e) { throw runtime.newIOErrorFromException(e); } } } return foundResource; }
/** * This method is designed to clear out classloader file locks in windows. * * @param clazzLdr class loader to clean up */ public void closeClassLoader() { HashSet<String> closedFiles = new HashSet<String>(); try { Object obj = getFieldObject(URLClassLoader.class, "ucp", this); ArrayList<?> loaders = (ArrayList<?>) getFieldObject(obj.getClass(), "loaders", obj); for (Object ldr : loaders) { try { JarFile file = (JarFile) getFieldObject(ldr.getClass(), "jar", ldr); closedFiles.add(file.getName()); file.close(); } catch (Exception e) { // skip } } } catch (Exception e) { // skip } try { Vector<?> nativeLibArr = (Vector<?>) getFieldObject(ClassLoader.class, "nativeLibraries", this); for (Object lib : nativeLibArr) { try { Method fMethod = lib.getClass().getDeclaredMethod("finalize", new Class<?>[0]); fMethod.setAccessible(true); fMethod.invoke(lib, new Object[0]); } catch (Exception e) { // skip } } } catch (Exception e) { // skip } HashMap<?, ?> uCache = null; HashMap<?, ?> fCache = null; try { Class<?> jarUrlConnClass = null; try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); jarUrlConnClass = contextClassLoader.loadClass("sun.net.www.protocol.jar.JarURLConnection"); } catch (Throwable skip) { // skip } if (jarUrlConnClass == null) { jarUrlConnClass = Class.forName("sun.net.www.protocol.jar.JarURLConnection"); } Class<?> factory = getFieldObject(jarUrlConnClass, "factory", null).getClass(); try { fCache = (HashMap<?, ?>) getFieldObject(factory, "fileCache", null); } catch (Exception e) { // skip } try { uCache = (HashMap<?, ?>) getFieldObject(factory, "urlCache", null); } catch (Exception e) { // skip } if (uCache != null) { Set<?> set = null; while (set == null) { try { set = ((HashMap<?, ?>) uCache.clone()).keySet(); } catch (ConcurrentModificationException e) { // Fix for BACKLOG-2149 - Do nothing - while loop will try again. } } for (Object file : set) { if (file instanceof JarFile) { JarFile jar = (JarFile) file; if (!closedFiles.contains(jar.getName())) { continue; } try { jar.close(); } catch (IOException e) { // skip } if (fCache != null) { fCache.remove(uCache.get(jar)); } uCache.remove(jar); } } } else if (fCache != null) { for (Object key : ((HashMap<?, ?>) fCache.clone()).keySet()) { Object file = fCache.get(key); if (file instanceof JarFile) { JarFile jar = (JarFile) file; if (!closedFiles.contains(jar.getName())) { continue; } try { jar.close(); } catch (IOException e) { // ignore } fCache.remove(key); } } } } catch (Exception e) { // skip e.printStackTrace(); } }