org.glassfish.loader.util.ASClassLoaderUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-embedded-all Show documentation
Show all versions of payara-embedded-all Show documentation
Payara-Embedded-All Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.loader.util;
import com.sun.enterprise.module.Module;
import com.sun.enterprise.module.ModulesRegistry;
import com.sun.enterprise.util.io.FileUtils;
import org.glassfish.api.deployment.DeployCommandParameters;
import org.glassfish.api.deployment.DeploymentContext;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.internal.api.ClassLoaderHierarchy;
import org.glassfish.internal.data.ApplicationRegistry;
import org.glassfish.internal.data.ApplicationInfo;
import org.glassfish.api.admin.ServerEnvironment;
import com.sun.enterprise.deployment.deploy.shared.Util;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.LogRecord;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.*;
import org.glassfish.logging.annotation.LogMessageInfo;
public class ASClassLoaderUtil {
public static final Logger deplLogger = org.glassfish.deployment.common.DeploymentContextImpl.deplLogger;
@LogMessageInfo(message = "Cannot convert classpath to URL {0}", level="WARNING")
private static final String CLASSPATH_ERROR = "NCLS-DEPLOYMENT-00045";
@LogMessageInfo(message = "Exception: {0}", level="WARNING")
private static final String EXCEPTION = "NCLS-DEPLOYMENT-00017";
@LogMessageInfo(message = "unexpected error in getting urls", level="WARNING")
private static final String UNEXPECTED_EXCEPTION = "NCLS-DEPLOYMENT-00018";
private static String modulesClassPath = null;
/** The manifest file name from an archive. */
private static final String MANIFEST_ENTRY =
"META-INF" + File.separator + "MANIFEST.MF";
/**
* Gets the classpath associated with a module, suffixing libraries
* defined [if any] for the application
*
* @param habitat the habitat the application resides in.
* @param moduleId Module id of the module
* @param deploymentLibs libraries option passed through deployment
* @return A File.pathSeparator
separated list of classpaths
* for the passed in module, including the module specified
* "libraries" defined for the module.
*/
public static String getModuleClassPath
(ServiceLocator habitat, String moduleId, String deploymentLibs) {
if (deplLogger.isLoggable(Level.FINE)) {
deplLogger.log(Level.FINE,
"ASClassLoaderUtil.getModuleClassPath " + "for module Id : " + moduleId);
}
StringBuilder classpath = new StringBuilder(getModulesClasspath(habitat));
ClassLoaderHierarchy clh =
habitat.getService(ClassLoaderHierarchy.class);
final String commonClassPath = clh.getCommonClassPath();
if (commonClassPath != null && commonClassPath.length() > 0) {
classpath.append(commonClassPath).append(File.pathSeparator);
}
addDeployParamLibrariesForModule(classpath, moduleId, deploymentLibs, habitat);
if (deplLogger.isLoggable(Level.FINE)) {
deplLogger.log(Level.FINE,
"Final classpath: " + classpath.toString());
}
return classpath.toString();
}
public static String getModuleClassPath (ServiceLocator habitat,
DeploymentContext context) {
DeployCommandParameters params =
context.getCommandParameters(DeployCommandParameters.class);
return getModuleClassPath(habitat, params.name(), params.libraries());
}
private static void addDeployParamLibrariesForModule(StringBuilder sb,
String moduleId, String deploymentLibs, ServiceLocator habitat) {
if (moduleId.indexOf("#") != -1) {
moduleId = moduleId.substring(0, moduleId.indexOf("#"));
}
if (deploymentLibs == null) {
ApplicationInfo appInfo =
habitat.getService(ApplicationRegistry.class).get(moduleId);
if (appInfo == null) {
// this might be an internal container app,
// like _default_web_app, ignore.
return;
}
deploymentLibs = appInfo.getLibraries();
}
final URL[] libs =
getDeployParamLibrariesAsURLs(deploymentLibs, habitat);
if (libs != null) {
for (final URL u : libs) {
sb.append(u.getPath());
sb.append(File.pathSeparator);
}
}
}
private static URL[] getDeployParamLibrariesAsURLs(String librariesStr,
ServiceLocator habitat) {
return getDeployParamLibrariesAsURLs(librariesStr,
habitat.getService(ServerEnvironment.class));
}
/**
* converts libraries specified via EXTENSION_LIST entry in MANIFEST.MF of
* all of the libraries of the deployed archive to
* The libraries are made available to
* the application in the order specified.
*
* @param librariesStr is a comma-separated list of library JAR files
* @param env the server environment
* @return array of URL
*/
public static URL[] getLibrariesAsURLs(Set librariesStr,
ServerEnvironment env) {
if(librariesStr == null)
return null;
final URL [] urls = new URL[librariesStr.size()];
String [] librariesStrArray = new String[librariesStr.size()];
librariesStrArray = librariesStr.toArray(librariesStrArray);
return getDeployParamLibrariesAsURLs(env, librariesStrArray, urls);
}
/**
* converts libraries specified via the --libraries deployment option to
* URL[]. The library JAR files are specified by either relative or
* absolute paths. The relative path is relative to
* instance-root/lib/applibs. The libraries are made available to
* the application in the order specified.
*
* @param librariesStr is a comma-separated list of library JAR files
* @param env the server environment
* @return array of URL
*/
public static URL[] getDeployParamLibrariesAsURLs(String librariesStr,
ServerEnvironment env) {
if(librariesStr == null)
return null;
String [] librariesStrArray = librariesStr.split(",");
final URL [] urls = new URL[librariesStrArray.length];
return getDeployParamLibrariesAsURLs(env, librariesStrArray, urls);
}
private static URL[] getDeployParamLibrariesAsURLs(ServerEnvironment env, String[] librariesStrArray,
URL[] urls) {
final String appLibsDir = env.getLibPath()
+ File.separator + "applibs";
int i=0;
for(final String libraryStr:librariesStrArray){
try {
File f = new File(libraryStr);
if(!f.isAbsolute())
f = new File(appLibsDir, libraryStr);
URL url =f.toURI().toURL();
urls[i++] = url;
} catch (MalformedURLException malEx) {
deplLogger.log(Level.WARNING,
CLASSPATH_ERROR,
libraryStr);
LogRecord lr = new LogRecord(Level.WARNING, EXCEPTION);
lr.setParameters(new Object[] { malEx.getMessage() });
lr.setThrown(malEx);
deplLogger.log(lr);
}
}
return urls;
}
private static synchronized String getModulesClasspath(ServiceLocator habitat) {
synchronized (ASClassLoaderUtil.class) {
if (modulesClassPath == null) {
final StringBuilder tmpString = new StringBuilder();
ModulesRegistry mr = habitat.getService(ModulesRegistry.class);
if (mr != null) {
for (Module module : mr.getModules()) {
for (URI uri : module.getModuleDefinition().getLocations()) {
tmpString.append(uri.getPath());
tmpString.append(File.pathSeparator);
}
}
}
//set shared classpath for module so that it doesn't need to be
//recomputed for every other invocation
modulesClassPath = tmpString.toString();
}
}
return modulesClassPath;
}
/**
* Returns an array of urls that contains ..
*
* i. all the valid directories from the given directory (dirs) array
* ii. all jar files from the given directory (jarDirs) array
* iii. all zip files from the given directory (jarDirs) array if
* not ignoring zip file (ignoreZip is false).
*
*
* @param dirs array of directory path names
* @param jarDirs array of path name to directories that contains
* JAR & ZIP files.
* @param ignoreZip whether to ignore zip files
* @return an array of urls that contains all the valid dirs,
* *.jar & *.zip
*
* @throws IOException if an i/o error while constructing the urls
*/
public static URL[] getURLs(File[] dirs, File[] jarDirs,
boolean ignoreZip) throws IOException {
return convertURLListToArray(getURLsAsList(dirs, jarDirs, ignoreZip));
}
/**
* Returns a list of urls that contains ..
*
* i. all the valid directories from the given directory (dirs) array
* ii. all jar files from the given directory (jarDirs) array
* iii. all zip files from the given directory (jarDirs) array if
* not ignoring zip file (ignoreZip is false).
*
*
* @param dirs array of directory path names
* @param jarDirs array of path name to directories that contains
* JAR & ZIP files.
* @param ignoreZip whether to ignore zip files
* @return an array of urls that contains all the valid dirs,
* *.jar & *.zip
*
* @throws IOException if an i/o error while constructing the urls
*/
public static List getURLsAsList(File[] dirs, File[] jarDirs,
boolean ignoreZip) throws IOException {
List list = new ArrayList();
// adds all directories
if (dirs != null) {
for (int i=0; i list) {
// converts the list to an array
URL[] urls = new URL[0];
if (list != null && list.size() > 0) {
urls = new URL[list.size()];
urls = (URL[]) list.toArray(urls);
}
return urls;
}
/**
* get URL list from classpath
* @param classpath classpath string containing the classpaths
* @param delimiter delimiter to separate the classpath components
* in the classpath string
* @param rootPath root path of the classpath if the paths are relative
* @return urlList URL list from the given classpath
*/
public static List getURLsFromClasspath(String classpath,
String delimiter, String rootPath) {
final List urls = new ArrayList();
if (classpath == null || classpath.length() == 0) {
return urls;
}
// tokenize classpath
final StringTokenizer st = new StringTokenizer(classpath, delimiter);
while (st.hasMoreTokens()) {
try {
String path = st.nextToken();
try {
// try to see if the path is absolute
URL url = new URL(path);
URI uri = url.toURI();
if (uri.isAbsolute()) {
urls.add(uri.toURL());
continue;
}
} catch (Exception ie) {
// ignore
}
if (rootPath != null && rootPath.length() != 0) {
path = rootPath + File.separator + path;
}
File f = new File(path);
urls.add(f.toURI().toURL());
} catch(Exception e) {
deplLogger.log(Level.WARNING,
UNEXPECTED_EXCEPTION,
e);
}
}
return urls;
}
/**
* Returns the manifest file for the given root path.
*
*
* Example:
* |--repository/
* | |--applications/
* | |--converter/
* | |--ejb-jar-ic_jar/ <---- rootPath
* | |--META-INF/
* | |--MANIFEST.MF
*
*
* @param rootPath absolute path to the module
*
* @return the manifest file for the given module
*/
public static Manifest getManifest(String rootPath) {
InputStream in = null;
Manifest mf = null;
// gets the input stream to the MANIFEST.MF file
try {
in = new FileInputStream(rootPath+File.separator+MANIFEST_ENTRY);
if (in != null) {
mf = new Manifest(in);
}
} catch (IOException ioe) {
// ignore
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ioe) {
// Ignore
}
}
}
return mf;
}
/**
* Returns the class path (if any) from the given manifest file as an
* URL list.
*
* @param manifest manifest file of an archive
* @param rootPath root path to the module
*
* @return a list of URLs
* an empty list if given manifest is null
*/
public static List getManifestClassPathAsURLs(Manifest manifest,
String rootPath) {
List urlList = new ArrayList();
if (manifest != null) {
Attributes mainAttributes = manifest.getMainAttributes();
for (Map.Entry entry : mainAttributes.entrySet()) {
Attributes.Name next = (Attributes.Name) entry.getKey();
if (next.equals(Attributes.Name.CLASS_PATH)) {
String classpathString = (String) entry.getValue();
urlList = getURLsFromClasspath(classpathString, " ",
rootPath);
}
}
}
return urlList;
}
/**
* add all the libraries packaged in the application library directory
*
* @param appRoot the application root
* @param appLibDir the Application library directory
* @param compatibilityProp the version of the release that we need to
* maintain backward compatibility
* @return an array of URL
*/
public static URL[] getAppLibDirLibraries(File appRoot, String appLibDir,
String compatibilityProp)
throws IOException {
return convertURLListToArray(
getAppLibDirLibrariesAsList(appRoot, appLibDir, compatibilityProp));
}
public static List getAppLibDirLibrariesAsList(File appRoot, String appLibDir, String compatibilityProp)
throws IOException {
URL[] libDirLibraries = new URL[0];
// get all the app lib dir libraries
if (appLibDir != null) {
String libPath = appLibDir.replace('/', File.separatorChar);
libDirLibraries = getURLs(null,
new File[] {new File(appRoot, libPath)}, true);
}
List allLibDirLibraries = new ArrayList();
for (URL url : libDirLibraries) {
allLibDirLibraries.add(url);
}
// if the compatibility property is set to "v2", we should add all the
// jars under the application root to maintain backward compatibility
// of v2 jar visibility
if (compatibilityProp != null && compatibilityProp.equals("v2")) {
List appRootLibraries = getURLsAsList(null, new File[] {appRoot}, true);
allLibDirLibraries.addAll(appRootLibraries);
}
return allLibDirLibraries;
}
public static List getLibDirectoryJarURIs(File moduleLibDirectory) throws Exception {
List libLibraryURIs = new ArrayList();
File[] jarFiles = moduleLibDirectory.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return (pathname.getAbsolutePath().endsWith(".jar"));
}
});
if (jarFiles != null && jarFiles.length > 0) {
for (File jarFile : jarFiles) {
libLibraryURIs.add(Util.toURI(jarFile.toURL()));
}
}
return libLibraryURIs;
}
}