emptySet());
/**
* Construct a new instance with the given parent class loader, which must be a concurrent class loader, or {@code null}
* to create a root concurrent class loader.
*
* @param parent the parent class loader
*/
protected ConcurrentClassLoader(final ConcurrentClassLoader parent) {
this(parent, null);
}
/**
* Construct a new instance, using our class loader as the parent.
*/
protected ConcurrentClassLoader() {
this((String) null);
}
/**
* Construct a new instance with the given parent class loader, which must be a concurrent class loader, or {@code null}
* to create a root concurrent class loader.
*
* @param parent the parent class loader
* @param name the name of this class loader, or {@code null} if it is unnamed
*/
protected ConcurrentClassLoader(final ConcurrentClassLoader parent, final String name) {
super(parent == null ? JDKSpecific.getPlatformClassLoader() : parent, name);
if (! JDKSpecific.isParallelCapable(this)) {
throw new Error("Cannot instantiate non-parallel subclass");
}
}
/**
* Construct a new instance, using our class loader as the parent.
*
* @param name the name of this class loader, or {@code null} if it is unnamed
*/
protected ConcurrentClassLoader(String name) {
super(JDKSpecific.getPlatformClassLoader(), name);
if (! JDKSpecific.isParallelCapable(this)) {
throw new Error("Cannot instantiate non-parallel subclass");
}
}
static Object getLockForClass(ConcurrentClassLoader cl, String name) {
return cl.getClassLoadingLock(name);
}
/**
* Loads the class with the specified binary name. Equivalent to calling {@link #loadClass(String, boolean) loadClass(className, false)}.
*
* @param className The binary name of the class
* @return the resulting {@code Class} instance
* @throws ClassNotFoundException if the class was not found
*/
@Override
public final Class> loadClass(final String className) throws ClassNotFoundException {
return performLoadClass(className, false, false);
}
/**
* Loads the class with the specified binary name.
*
* @param className The binary name of the class
* @param resolve {@code true} if the class should be linked after loading
* @return the resulting {@code Class} instance
*/
@Override
public final Class> loadClass(final String className, boolean resolve) throws ClassNotFoundException {
return performLoadClass(className, false, resolve);
}
/**
* Same as {@link #loadClass(String)}, except only exported classes will be considered.
*
* @param className the class name
* @return the class
* @throws ClassNotFoundException if the class isn't found
*/
public final Class> loadExportedClass(final String className) throws ClassNotFoundException {
return performLoadClass(className, true, false);
}
/**
* Same as {@link #loadClass(String,boolean)}, except only exported classes will be considered.
*
* @param className the class name
* @param resolve {@code true} if the class should be linked after loading
* @return the class
* @throws ClassNotFoundException if the class isn't found
*/
public final Class> loadExportedClass(final String className, boolean resolve) throws ClassNotFoundException {
return performLoadClass(className, true, resolve);
}
/**
* Find a class, possibly delegating to other loader(s). This method should never synchronize across a
* delegation method call of any sort. The default implementation always throws {@code ClassNotFoundException}.
*
* If a class is to be defined by this method, it should be done via one of the atomic {@code defineOrLoadClass}
* methods rather than {@code defineClass()} in order to avoid spurious exceptions.
*
* @param className the class name
* @param exportsOnly {@code true} if only exported classes should be considered
* @param resolve {@code true} if the class should be linked after loading
* @return the class
* @throws ClassNotFoundException if the class is not found
*/
protected Class> findClass(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
throw new ClassNotFoundException(className);
}
/**
* Atomically define or load the named class. If the class is already defined, the existing class is returned.
*
* @param className the class name to define or load
* @param bytes the bytes to use to define the class
* @param off the offset into the byte array at which the class bytes begin
* @param len the number of bytes in the class
* @return the class
*/
protected final Class> defineOrLoadClass(final String className, final byte[] bytes, int off, int len) {
try {
final Class> definedClass = defineClass(className, bytes, off, len);
return definedClass;
} catch (LinkageError e) {
final Class> loadedClass = findLoadedClass(className);
if (loadedClass != null) {
return loadedClass;
}
throw e;
}
}
/**
* Atomically define or load the named class. If the class is already defined, the existing class is returned.
*
* @param className the class name to define or load
* @param bytes the bytes to use to define the class
* @param off the offset into the byte array at which the class bytes begin
* @param len the number of bytes in the class
* @param protectionDomain the protection domain for the defined class
* @return the class
*/
protected final Class> defineOrLoadClass(final String className, final byte[] bytes, int off, int len, ProtectionDomain protectionDomain) {
try {
return defineClass(className, bytes, off, len, protectionDomain);
} catch (LinkageError e) {
final Class> loadedClass = findLoadedClass(className);
if (loadedClass != null) {
return loadedClass;
}
throw e;
}
}
/**
* Implementation of {@link ClassLoader#findClass(String)}.
*
* @param className the class name
* @return the result of {@code findClass(className, false, false)}
*/
protected final Class> findClass(final String className) throws ClassNotFoundException {
return findClass(className, false, false);
}
/**
* Implementation of {@link ClassLoader#findClass(String, String)}.
*
* @param moduleName the Java module name
* @param className the class name
* @return the result of {@code findClass(className, false, false)}
*/
protected final Class> findClass(final String moduleName, final String className) {
try {
return findClass(className);
} catch (ClassNotFoundException e) {
return null;
}
}
/**
* Finds the resource with the given name. The name of a resource is a {@code '/'}-separated path name that
* identifies the resource. If the resource name starts with {@code "java/"} then the parent class loader is used.
* Otherwise, this method delegates to {@link #findResource(String, boolean)}.
*
* @param name the name of the resource
* @return the resource URL, or {@code null} if no such resource exists or the invoker does not have adequate
* permission to access it
*/
public final URL getResource(final String name) {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
return JDKSpecific.getSystemResource(name);
}
}
return findResource(name, false);
}
/**
* Finds all available resources with the given name.
*
* @see #getResource(String)
*
* @param name the resource name
* @return an enumeration over all the resource URLs; if no resources could be found, the enumeration will be empty
* @throws IOException if an I/O error occurs
*/
public final Enumeration getResources(final String name) throws IOException {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
return JDKSpecific.getSystemResources(name);
}
}
return findResources(name, false);
}
/**
* Find the resource with the given name and exported status.
*
* @see #getResource(String)
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource URL
*/
protected URL findResource(final String name, final boolean exportsOnly) {
return null;
}
/**
* Never used. {@link ClassLoader#getResource(String)} and related methods can cause a loop condition
* when this method is implemented; use {@link #findResource(String, boolean)} instead.
*
* @param name ignored
* @return {@code null} always
*/
protected final URL findResource(final String name) {
// Always return null so that we don't go into a loop from super.getResource*().
return null;
}
/**
* Find the resource with the given name in specified java module.
*
* @see #getResource(String)
*
* @param moduleName java module name
* @param name the resource name
* @return the resource URL
*/
protected final URL findResource(final String moduleName, final String name) throws IOException {
return getResource(name);
}
/**
* Finds the resources with the given name and exported status.
*
* @see #getResources(String)
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource enumeration
* @throws IOException if an I/O error occurs
*/
protected Enumeration findResources(final String name, final boolean exportsOnly) throws IOException {
return EMPTY_ENUMERATION;
}
/**
* Never used. {@link ClassLoader#getResources(String)} and related methods can cause a loop condition
* when this method is implemented; use {@link #findResources(String, boolean)} instead. By default, returns
* an empty enumeration.
*
* @param name ignored
* @return an empty enumeration
*/
protected final Enumeration findResources(final String name) {
return EMPTY_ENUMERATION;
}
/**
* Finds the resource with the given name and exported status, returning the resource content as a stream.
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource stream, or {@code null} if the resource is not found
*/
protected InputStream findResourceAsStream(final String name, final boolean exportsOnly) {
final URL url = findResource(name, exportsOnly);
try {
return url == null ? null : url.openStream();
} catch (IOException e) {
return null;
}
}
/**
* Returns an input stream for reading the specified resource. This method delegates to {@link #findResourceAsStream(String, boolean)}.
*
* @param name the resource name
* @return the resource stream, or {@code null} if the resource is not found
*/
public final InputStream getResourceAsStream(final String name) {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
return JDKSpecific.getSystemResourceAsStream(name);
}
}
return findResourceAsStream(name, false);
}
// Private members
/**
* Perform a class load operation. If the class is in the package or a subpackage of a package in the system packages list,
* the parent class loader is used to load the class. Otherwise, this method checks to see if the class loader
* object is locked; if so, it unlocks it and submits the request to the class loader thread. Otherwise, it will
* load the class itself by delegating to {@link #findClass(String, boolean, boolean)}.
*
* @param className the class name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @param resolve {@code true} to resolve the loaded class
* @return the class returned by {@link #findClass(String, boolean, boolean)}
* @throws ClassNotFoundException if {@link #findClass(String, boolean, boolean)} throws this exception
*/
private Class> performLoadClass(String className, boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
if (className == null) {
throw new IllegalArgumentException("name is null");
}
if (className.length() == 0) {
throw new IllegalArgumentException("name is empty");
}
for (String s : Module.systemPackages) {
if (className.startsWith(s)) {
return JDKSpecific.getSystemClass(this, className);
}
}
return performLoadClassUnchecked(className, exportsOnly, resolve);
}
private Class> performLoadClassUnchecked(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
if (className.charAt(0) == '[') {
// Use Class.forName to load the array type
final Class> array = Class.forName(className, false, this);
if (resolve) {
resolveClass(array);
}
return array;
}
return findClass(className, exportsOnly, resolve);
}
private final ConcurrentHashMap packages = new ConcurrentHashMap<>();
Class> findSystemClassInternal(String name) throws ClassNotFoundException {
return findSystemClass(name);
}
/**
* Load a package which is visible to this class loader.
*
* @param name the package name
* @return the package, or {@code null} if no such package is visible to this class loader
*/
protected final Package getPackage(final String name) {
final String packageName = name + ".";
for (String s : Module.systemPackages) {
if (packageName.startsWith(s)) {
return Package.getPackage(name);
}
}
if (GET_PACKAGE_SUPPRESSOR.get() == Boolean.TRUE) {
return null;
}
return getPackageByName(name);
}
/**
* Perform the actual work to load a package which is visible to this class loader. By default, uses a simple
* parent-first delegation strategy.
*
* @param name the package name
* @return the package, or {@code null} if no such package is visible to this class loader
*/
protected Package getPackageByName(final String name) {
final Package parentPackage = super.getPackage(name);
return parentPackage == null ? findLoadedPackage(name) : parentPackage;
}
/**
* Get all defined packages which are visible to this class loader.
*
* @return the packages
*/
protected Package[] getPackages() {
ArrayList list = new ArrayList();
list.addAll(packages.values());
list.addAll(Arrays.asList(super.getPackages()));
return list.toArray(new Package[list.size()]);
}
/**
* Load a package from this class loader only.
*
* @param name the package name
* @return the package or {@code null} if no such package is defined by this class loader
*/
protected final Package findLoadedPackage(final String name) {
return packages.get(name);
}
/**
* Defines a package by name in this ConcurrentClassLoader. If the package was already defined, the
* existing package is returned instead.
*
* @param name the package name
* @param specTitle the specification title
* @param specVersion the specification version
* @param specVendor the specification vendor
* @param implTitle the implementation title
* @param implVersion the implementation version
* @param implVendor the implementation vendor
* @param sealBase if not {@code null}, then this package is sealed with respect to the given code source URL
*
* @return the newly defined package, or the existing one if one was already defined
*/
protected Package definePackage(final String name, final String specTitle, final String specVersion, final String specVendor, final String implTitle, final String implVersion, final String implVendor, final URL sealBase) throws IllegalArgumentException {
ThreadLocal suppressor = GET_PACKAGE_SUPPRESSOR;
suppressor.set(Boolean.TRUE);
try {
Package existing = packages.get(name);
if (existing != null) {
return existing;
}
Package pkg;
try {
pkg = super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
} catch (final IllegalArgumentException iae) {
pkg = super.getPackage(name);
if (pkg == null) throw iae;
}
existing = packages.putIfAbsent(name, pkg);
return existing != null ? existing : pkg;
} finally {
suppressor.remove();
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DataURLStreamHandler.java 0000664 0000000 0000000 00000024634 13417133242 0030134 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLStreamHandler;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Base64;
/**
*/
final class DataURLStreamHandler extends URLStreamHandler {
private static final DataURLStreamHandler INSTANCE = new DataURLStreamHandler();
static DataURLStreamHandler getInstance() {
return INSTANCE;
}
private DataURLStreamHandler() {
}
protected URLConnection openConnection(final URL url) throws IOException {
return new DataURLConnection(url);
}
static final class DataURLConnection extends URLConnection {
private static final int ST_INITIAL = 0;
private static final int ST_TYPE = 1;
private static final int ST_SUBTYPE = 2;
private static final int ST_PARAMETER = 3;
private static final int ST_PARAMETER_VAL = 4;
private final byte[] content;
private final String contentString;
private final String contentType;
DataURLConnection(final URL url) throws IOException {
super(url);
// We have to use toString() because otherwise URL will eat '?' characters in the content!
String urlString = url.toString();
if (! urlString.startsWith("data:")) {
// should not happen
throw new ProtocolException("Wrong URL scheme");
}
String contentType = "text/plain";
StringBuilder contentTypeBuilder = null;
int state = ST_INITIAL;
final int len = urlString.length();
int cp;
int postCt = -1;
int content = -1;
int paramStart = -1;
int paramEnd = -1;
boolean base64 = false;
String charsetName = null;
boolean text = true;
Charset charset = StandardCharsets.US_ASCII;
for (int i = 5; i < len; i = urlString.offsetByCodePoints(i, 1)) {
cp = urlString.codePointAt(i);
if (state == ST_INITIAL) {
if (isCTToken(cp)) {
state = ST_TYPE;
contentTypeBuilder = new StringBuilder();
contentTypeBuilder.appendCodePoint(Character.toLowerCase(cp));
} else if (cp == ';') {
// default content-type
contentTypeBuilder = new StringBuilder();
contentTypeBuilder.append("text/plain");
postCt = contentTypeBuilder.length();
paramStart = urlString.offsetByCodePoints(i, 1);
state = ST_PARAMETER;
} else if (cp == ',') {
content = urlString.offsetByCodePoints(i, 1);
// done
break;
} else {
throw invalidChar(i);
}
} else if (state == ST_TYPE) {
if (isCTToken(cp)) {
contentTypeBuilder.appendCodePoint(Character.toLowerCase(cp));
} else if (cp == '/') {
state = ST_SUBTYPE;
contentTypeBuilder.append('/');
} else {
throw invalidChar(i);
}
} else if (state == ST_SUBTYPE) {
if (isCTToken(cp)) {
contentTypeBuilder.appendCodePoint(Character.toLowerCase(cp));
} else if (cp == ';') {
postCt = contentTypeBuilder.length();
paramStart = urlString.offsetByCodePoints(i, 1);
state = ST_PARAMETER;
} else if (cp == ',') {
contentType = contentTypeBuilder.toString();
text = contentType.startsWith("text/");
content = urlString.offsetByCodePoints(i, 1);
// done
break;
} else {
throw invalidChar(i);
}
} else if (state == ST_PARAMETER) {
if (isCTToken(cp)) {
// OK
} else if (cp == ';' || cp == ',') {
// no value
if (i - paramStart == 6 && urlString.regionMatches(true, paramStart, "base64", 0, 6)) {
base64 = true;
} else {
contentTypeBuilder.append(';').append(urlString.substring(paramStart, i));
}
if (cp == ',') {
text = contentTypeBuilder.lastIndexOf("text/", 5) != -1;
if (text && charsetName != null) {
contentTypeBuilder.insert(postCt, ";charset=" + charsetName);
}
contentType = contentTypeBuilder.toString();
content = urlString.offsetByCodePoints(i, 1);
// done
break;
}
paramStart = urlString.offsetByCodePoints(i, 1);
// restart ST_PARAMETER
} else if (cp == '=') {
paramEnd = i;
state = ST_PARAMETER_VAL;
} else {
throw invalidChar(i);
}
} else if (state == ST_PARAMETER_VAL) {
if (isCTToken(cp)) {
// OK
} else if (cp == ';' || cp == ',') {
// there is a value
final String value = urlString.substring(paramEnd + 1, i);
if (paramEnd - paramStart == 7 && urlString.regionMatches(true, paramStart, "charset", 0, 7)) {
try {
charset = Charset.forName(value);
} catch (UnsupportedCharsetException e) {
throw e;
} catch (Throwable t) {
final UnsupportedCharsetException uce = new UnsupportedCharsetException(value);
uce.initCause(t);
throw uce;
}
charsetName = value;
} else {
contentTypeBuilder.append(urlString.substring(paramStart, i));
}
if (cp == ',') {
text = contentTypeBuilder.lastIndexOf("text/", 5) != -1;
if (text && charsetName != null) {
contentTypeBuilder.insert(postCt, ";charset=" + charsetName);
}
contentType = contentTypeBuilder.toString();
content = urlString.offsetByCodePoints(i, 1);
// done
break;
}
state = ST_PARAMETER;
} else {
throw invalidChar(i);
}
} else {
throw new IllegalStateException();
}
}
if (content == -1) {
throw new ProtocolException("Missing content");
}
// now, get the content
byte[] bytes;
String str;
if (base64) {
bytes = Base64.getMimeDecoder().decode(urlString.substring(content).replaceAll("\\s+", ""));
if (text) {
str = new String(bytes, charset);
} else {
str = null;
}
} else {
if (text) {
str = URLDecoder.decode(urlString.substring(content), charset.name());
bytes = str.getBytes(charset);
} else {
// this is a bit hacky...
bytes = URLDecoder.decode(urlString.substring(content), StandardCharsets.ISO_8859_1.name()).getBytes(StandardCharsets.ISO_8859_1);
str = null;
}
}
this.content = bytes;
this.contentType = contentType;
this.contentString = str;
}
private static ProtocolException invalidChar(int pos) {
return new ProtocolException("Invalid character at position " + pos);
}
private static boolean isCTToken(int cp) {
return 0x21 <= cp && cp <= 0x7e &&
cp != '(' && cp != ')' && cp != '<' && cp != '>' && cp != '@' &&
cp != ',' && cp != ';' && cp != ':' && cp != '\\' && cp != '"' &&
cp != '/' && cp != '[' && cp != ']' && cp != '?' && cp != '=';
}
public void connect() {
connected = true;
}
public int getContentLength() {
return content.length;
}
public String getContentType() {
return contentType;
}
public Object getContent() {
return contentString != null ? contentString : content.clone();
}
public InputStream getInputStream() {
return new ByteArrayInputStream(content);
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DefaultBootModuleLoaderHolder.java 0000664 0000000 0000000 00000004543 13417133242 0032066 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
final class DefaultBootModuleLoaderHolder {
static final ModuleLoader INSTANCE;
private DefaultBootModuleLoaderHolder() {
}
static {
INSTANCE = AccessController.doPrivileged(new PrivilegedAction() {
public ModuleLoader run() {
final String loaderClass = System.getProperty("boot.module.loader", LocalModuleLoader.class.getName());
try {
return Class.forName(loaderClass, true, DefaultBootModuleLoaderHolder.class.getClassLoader()).asSubclass(ModuleLoader.class).getConstructor().newInstance();
} catch (InstantiationException e) {
throw new InstantiationError(e.getMessage());
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InvocationTargetException e) {
try {
throw e.getCause();
} catch (RuntimeException cause) {
throw cause;
} catch (Error cause) {
throw cause;
} catch (Throwable t) {
throw new Error(t);
}
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.getMessage());
}
}
});
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DelegatingModuleLoader.java 0000664 0000000 0000000 00000004501 13417133242 0030555 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
/**
* A module loader which searches its finders first, and then delegates to another loader if the module is not found.
*/
public class DelegatingModuleLoader extends ModuleLoader {
private final ModuleLoader delegate;
/**
* Construct a new instance.
*
* @param delegate the delegate module loader, or {@code null} to skip delegation
* @param finders the module finders (must not be {@code null})
*/
public DelegatingModuleLoader(final ModuleLoader delegate, final ModuleFinder[] finders) {
super(finders);
this.delegate = delegate;
}
/**
* Construct a new instance.
*
* @param delegate the delegate module loader, or {@code null} to skip delegation
* @param finder the single module finder (must not be {@code null})
*/
public DelegatingModuleLoader(final ModuleLoader delegate, final ModuleFinder finder) {
super(finder);
this.delegate = delegate;
}
/**
* Preload the named module.
*
* @param name the module name (must not be {@code null})
* @return the loaded module, or {@code null} if it is not found in this loader or the delegate
* @throws ModuleLoadException if the module was found but failed to be loaded
*/
protected Module preloadModule(final String name) throws ModuleLoadException {
Module module = loadModuleLocal(name);
if (module == null) {
final ModuleLoader delegate = this.delegate;
if (delegate != null) {
module = preloadModule(name, delegate);
}
}
return module;
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/Dependency.java 0000664 0000000 0000000 00000007514 13417133242 0026302 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency item.
*
* @author John Bailey
* @author David M. Lloyd
*/
abstract class Dependency {
private final PathFilter exportFilter;
private final PathFilter importFilter;
private final PathFilter resourceExportFilter;
private final PathFilter resourceImportFilter;
private final ClassFilter classExportFilter;
private final ClassFilter classImportFilter;
Dependency(final PathFilter exportFilter, final PathFilter importFilter) {
this(exportFilter, importFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll());
}
protected Dependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter) {
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
this.exportFilter = exportFilter;
this.importFilter = importFilter;
this.resourceExportFilter = resourceExportFilter;
this.resourceImportFilter = resourceImportFilter;
this.classExportFilter = classExportFilter;
this.classImportFilter = classImportFilter;
}
/**
* Get the export filter for this dependency. This filter determines what imported paths are re-exported by this
* dependency. All exported paths must also satisfy the import filter.
*
* @return the export filter
*/
final PathFilter getExportFilter() {
return exportFilter;
}
/**
* Get the import filter for this dependency. This filter determines what exported paths are imported from the
* dependency to the dependent.
*
* @return the import filter
*/
final PathFilter getImportFilter() {
return importFilter;
}
final PathFilter getResourceExportFilter() {
return resourceExportFilter;
}
final PathFilter getResourceImportFilter() {
return resourceImportFilter;
}
final ClassFilter getClassExportFilter() {
return classExportFilter;
}
final ClassFilter getClassImportFilter() {
return classImportFilter;
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DependencySpec.java 0000664 0000000 0000000 00000067232 13417133242 0027120 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency specification that represents a single dependency for a module. The dependency can be on a local loader
* or another module, or on the target module's local loader.
*
* @apiviz.exclude
*
* @author David M. Lloyd
* @author John Bailey
* @author Jason T. Greene
*/
public abstract class DependencySpec {
static final DependencySpec[] NO_DEPENDENCIES = new DependencySpec[0];
final PathFilter importFilter;
final PathFilter exportFilter;
final PathFilter resourceImportFilter;
final PathFilter resourceExportFilter;
final ClassFilter classImportFilter;
final ClassFilter classExportFilter;
/**
* Get the dependency import filter.
*
* @return the import filter
*/
public PathFilter getImportFilter() {
return importFilter;
}
/**
* Get the dependency export filter.
*
* @return the export filter
*/
public PathFilter getExportFilter() {
return exportFilter;
}
/**
* Get the dependency resource import filter.
*
* @return the import filter
*/
public PathFilter getResourceImportFilter() {
return resourceImportFilter;
}
/**
* Get the dependency resource export filter.
*
* @return the export filter
*/
public PathFilter getResourceExportFilter() {
return resourceExportFilter;
}
/**
* Get the dependency class import filter.
*
* @return the class import filter
*/
public ClassFilter getClassImportFilter() {
return classImportFilter;
}
/**
* Get the dependency class export filter.
*
* @return the class export filter
*/
public ClassFilter getClassExportFilter() {
return classExportFilter;
}
DependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) {
this.importFilter = importFilter;
this.exportFilter = exportFilter;
this.resourceImportFilter = resourceImportFilter;
this.resourceExportFilter = resourceExportFilter;
this.classImportFilter = classImportFilter;
this.classExportFilter = classExportFilter;
}
abstract Dependency getDependency(final Module module);
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources. Always returns {@link #OWN_DEPENDENCY}.
*
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec() {
return OWN_DEPENDENCY;
}
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter) {
return new LocalDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.build();
}
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) {
return new LocalDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setResourceImportFilter(resourceImportFilter)
.setResourceExportFilter(resourceExportFilter)
.setClassImportFilter(classImportFilter)
.setClassExportFilter(classExportFilter)
.build();
}
/**
* Create a system dependency.
*
* @param loaderPaths the set of paths to use from the system class loader
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final Set loaderPaths) {
return new LocalDependencySpecBuilder()
.setImportFilter(PathFilters.acceptAll())
.setLocalLoader(ClassLoaderLocalLoader.SYSTEM)
.setLoaderPaths(loaderPaths)
.build();
}
/**
* Create a system dependency.
*
* @param loaderPaths the set of paths to use from the system class loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final Set loaderPaths, boolean export) {
return new LocalDependencySpecBuilder()
.setLocalLoader(ClassLoaderLocalLoader.SYSTEM)
.setImportFilter(PathFilters.acceptAll())
.setLoaderPaths(loaderPaths)
.setExport(export)
.build();
}
/**
* Create a system dependency.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param loaderPaths the set of paths to use from the system class loader
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final Set loaderPaths) {
return new LocalDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setLocalLoader(ClassLoaderLocalLoader.SYSTEM)
.setLoaderPaths(loaderPaths)
.build();
}
/**
* Create a dependency on the given class loader.
*
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths) {
return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths);
}
/**
* Create a dependency on the given class loader.
*
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths, boolean export) {
return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths, export);
}
/**
* Create a dependency on the given class loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createClassLoaderDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ClassLoader classLoader, final Set loaderPaths) {
return createLocalDependencySpec(importFilter, exportFilter, new ClassLoaderLocalLoader(classLoader), loaderPaths);
}
/**
* Create a dependency on the given local loader.
*
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths) {
return new LocalDependencySpecBuilder()
.setLocalLoader(localLoader)
.setLoaderPaths(loaderPaths)
.build();
}
/**
* Create a dependency on the given local loader.
*
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths, boolean export) {
return new LocalDependencySpecBuilder()
.setLocalLoader(localLoader)
.setLoaderPaths(loaderPaths)
.setExport(export)
.build();
}
/**
* Create a dependency on the given local loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final LocalLoader localLoader, final Set loaderPaths) {
return new LocalDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setLocalLoader(localLoader)
.setLoaderPaths(loaderPaths)
.build();
}
/**
* Create a dependency on the given local loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*
* @deprecated Use {@link LocalDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final LocalLoader localLoader, final Set loaderPaths) {
return new LocalDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setResourceImportFilter(resourceImportFilter)
.setResourceExportFilter(resourceExportFilter)
.setClassImportFilter(classImportFilter)
.setClassExportFilter(classExportFilter)
.setLocalLoader(localLoader)
.setLoaderPaths(loaderPaths)
.build();
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier) {
return createModuleDependencySpec(identifier.toString());
}
/**
* Create a dependency on the given module.
*
* @param name the module name
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final String name) {
return new ModuleDependencySpecBuilder()
.setName(name)
.build();
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @param export {@code true} if the dependency should be exported by default
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export) {
return createModuleDependencySpec(identifier.toString(), export);
}
/**
* Create a dependency on the given module.
*
* @param name the module name
* @param export {@code true} if the dependency should be exported by default
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final String name, final boolean export) {
return new ModuleDependencySpecBuilder()
.setName(name)
.setExport(export)
.build();
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export, final boolean optional) {
return createModuleDependencySpec(identifier.toString(), export, optional);
}
/**
* Create a dependency on the given module.
*
* @param name the module name
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final String name, final boolean export, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setName(name)
.setExport(export)
.setOptional(optional)
.build();
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export) {
return createModuleDependencySpec(moduleLoader, identifier.toString(), export);
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param name the module name
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final String name, final boolean export) {
return new ModuleDependencySpecBuilder()
.setModuleLoader(moduleLoader)
.setName(name)
.setExport(export)
.build();
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export, final boolean optional) {
return createModuleDependencySpec(moduleLoader, identifier.toString(), export, optional);
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param name the module name
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final String name, final boolean export, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setModuleLoader(moduleLoader)
.setName(name)
.setExport(export)
.setOptional(optional)
.build();
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(exportFilter, identifier.toString(), optional);
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param name the module name
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final String name, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setExportFilter(exportFilter)
.setName(name)
.setOptional(optional)
.build();
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(exportFilter, moduleLoader, identifier.toString(), optional);
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param name the module name
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleLoader moduleLoader, final String name, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setExportFilter(exportFilter)
.setModuleLoader(moduleLoader)
.setName(name)
.setOptional(optional)
.build();
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), moduleLoader, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param name the module name
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ModuleLoader moduleLoader, final String name, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setModuleLoader(moduleLoader)
.setName(name)
.setOptional(optional)
.build();
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter, moduleLoader, identifier.toString(), optional);
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param name the module name
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*
* @deprecated Use {@link ModuleDependencySpecBuilder} instead.
*/
@Deprecated
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final ModuleLoader moduleLoader, final String name, final boolean optional) {
return new ModuleDependencySpecBuilder()
.setImportFilter(importFilter)
.setExportFilter(exportFilter)
.setResourceImportFilter(resourceImportFilter)
.setResourceExportFilter(resourceExportFilter)
.setClassImportFilter(classImportFilter)
.setClassExportFilter(classExportFilter)
.setModuleLoader(moduleLoader)
.setName(name)
.setOptional(optional)
.build();
}
/**
* A constant dependency which always represents a module's own content.
*/
public static final DependencySpec OWN_DEPENDENCY = new LocalDependencySpecBuilder().setExportFilter(PathFilters.acceptAll()).build();
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DependencySpecBuilder.java 0000664 0000000 0000000 00000016225 13417133242 0030423 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* The base class of dependency specification builders.
*/
public abstract class DependencySpecBuilder {
PathFilter importFilter = PathFilters.getDefaultImportFilter();
PathFilter exportFilter = PathFilters.rejectAll();
PathFilter resourceImportFilter = PathFilters.acceptAll();
PathFilter resourceExportFilter = PathFilters.acceptAll();
ClassFilter classImportFilter = ClassFilters.acceptAll();
ClassFilter classExportFilter = ClassFilters.acceptAll();
/**
* Construct a new instance.
*/
public DependencySpecBuilder() {
}
/**
* Get the import filter to use. The default value is {@link PathFilters#getDefaultImportFilter()}.
*
* @return the import filter to use
*/
public PathFilter getImportFilter() {
return importFilter;
}
/**
* Set the import filter to use.
*
* @param importFilter the import filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setImportFilter(final PathFilter importFilter) {
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
this.importFilter = importFilter;
return this;
}
/**
* Set a simple import filter, based on a {@code boolean} flag specifying whether services should be
* imported. If the flag is {@code true}, the import filter is set to {@link PathFilters#getDefaultImportFilterWithServices()},
* otherwise it is set to {@link PathFilters#getDefaultImportFilter()}. Any previous import filter setting is
* overwritten.
*
* @param services the services flag
* @return this builder
*/
public DependencySpecBuilder setImportServices(final boolean services) {
return setImportFilter(services ? PathFilters.getDefaultImportFilterWithServices() : PathFilters.getDefaultImportFilter());
}
/**
* Get the export filter to use. The default value is {@link PathFilters#rejectAll()}.
*
* @return the export filter to use
*/
public PathFilter getExportFilter() {
return exportFilter;
}
/**
* Set the export filter to use.
*
* @param exportFilter the export filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setExportFilter(final PathFilter exportFilter) {
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
this.exportFilter = exportFilter;
return this;
}
/**
* Set a simple export filter, based on a {@code boolean} flag. If the flag is {@code true}, the
* export filter is set to {@link PathFilters#acceptAll()}, otherwise it is set to {@link PathFilters#rejectAll()}.
* Any previous export filter setting is overwritten.
*
* @param export the export flag
* @return this builder
*/
public DependencySpecBuilder setExport(final boolean export) {
return setExportFilter(export ? PathFilters.acceptAll() : PathFilters.rejectAll());
}
/**
* Get the resource import filter to use. The default value is {@link PathFilters#acceptAll()}.
*
* @return the resource import filter to use
*/
public PathFilter getResourceImportFilter() {
return resourceImportFilter;
}
/**
* Set the resource import filter to use.
*
* @param resourceImportFilter the resource import filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setResourceImportFilter(final PathFilter resourceImportFilter) {
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
this.resourceImportFilter = resourceImportFilter;
return this;
}
/**
* Get the resource export filter to use. The default value is {@link PathFilters#acceptAll()}.
*
* @return the resource export filter to use
*/
public PathFilter getResourceExportFilter() {
return resourceExportFilter;
}
/**
* Set the resource export filter to use. The default value is {@link PathFilters#acceptAll()}.
*
* @param resourceExportFilter the resource export filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setResourceExportFilter(final PathFilter resourceExportFilter) {
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
this.resourceExportFilter = resourceExportFilter;
return this;
}
/**
* Get the class import filter to use. The default value is {@link ClassFilters#acceptAll()}.
*
* @return the class import filter to use
*/
public ClassFilter getClassImportFilter() {
return classImportFilter;
}
/**
* Set the class import filter to use.
*
* @param classImportFilter the class import filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setClassImportFilter(final ClassFilter classImportFilter) {
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
this.classImportFilter = classImportFilter;
return this;
}
/**
* Get the class export filter to use. The default value is {@link ClassFilters#acceptAll()}.
*
* @return the class export filter to use
*/
public ClassFilter getClassExportFilter() {
return classExportFilter;
}
/**
* Set the class export filter to use.
*
* @param classExportFilter the class export filter to use (must not be {@code null})
* @return this builder
*/
public DependencySpecBuilder setClassExportFilter(final ClassFilter classExportFilter) {
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
this.classExportFilter = classExportFilter;
return this;
}
/**
* Construct the dependency specification.
*
* @return the dependency specification
*/
public abstract DependencySpec build();
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/DependencyTreeViewer.java 0000664 0000000 0000000 00000012742 13417133242 0030303 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency tree viewer utility. Prints out the dependency tree for a module.
*/
public final class DependencyTreeViewer {
private static O[] filtered(Class oType, I... inputs) {
final I[] newArray = Arrays.copyOf(inputs, inputs.length);
int o = 0;
for (int i = 0; i < inputs.length; i ++) {
if (oType.getComponentType().isInstance(inputs[i])) {
newArray[o++] = (O) inputs[i];
}
}
return Arrays.copyOf(newArray, o, oType);
}
private static void print(PrintWriter out, String prefix, ModuleSpec spec, FastCopyHashSet visited, File... roots) {
if (spec instanceof AliasModuleSpec) {
final AliasModuleSpec aliasModuleSpec = (AliasModuleSpec) spec;
out.print(" -> ");
final String aliasTarget = aliasModuleSpec.getAliasName();
out.println(aliasTarget);
if (visited.add(aliasTarget)) {
try {
final ModuleSpec moduleSpec = LocalModuleFinder.parseModuleXmlFile(aliasTarget, null, roots);
print(out, prefix, moduleSpec, visited);
} catch (IOException e) {
out.println(e);
} catch (ModuleLoadException e) {
out.println(e);
}
}
} else if (spec instanceof ConcreteModuleSpec) {
out.println();
final ConcreteModuleSpec concreteModuleSpec = (ConcreteModuleSpec) spec;
final DependencySpec[] dependencies = filtered(ModuleDependencySpec[].class, concreteModuleSpec.getDependencies());
for (int i = 0, dependenciesLength = dependencies.length; i < dependenciesLength; i++) {
print(out, prefix, dependencies[i], visited, i == dependenciesLength - 1, roots);
}
} else {
out.println();
}
}
private static void print(PrintWriter out, String prefix, DependencySpec spec, FastCopyHashSet visited, final boolean last, final File... roots) {
if (spec instanceof ModuleDependencySpec) {
final ModuleDependencySpec moduleDependencySpec = (ModuleDependencySpec) spec;
final String name = moduleDependencySpec.getName();
out.print(prefix);
out.print(last ? '└' : '├');
out.print('─');
out.print(' ');
out.print(name);
if (moduleDependencySpec.isOptional()) {
out.print(" (optional)");
}
final PathFilter exportFilter = moduleDependencySpec.getExportFilter();
if (! exportFilter.equals(PathFilters.rejectAll())) {
out.print(" (exported)");
}
if (visited.add(name)) {
print(out, prefix + (last ? " " : "│ "), name, visited, roots);
} else {
out.println();
}
}
}
private static void print(PrintWriter out, String prefix, String name, FastCopyHashSet visited, final File... roots) {
final ModuleSpec moduleSpec;
try {
moduleSpec = LocalModuleFinder.parseModuleXmlFile(name, null, roots);
if (moduleSpec == null) {
out.println(" (not found)");
} else {
print(out, prefix, moduleSpec, visited, roots);
}
} catch (IOException e) {
out.print(" (");
out.print(e);
out.println(")");
} catch (ModuleLoadException e) {
out.print(" (");
out.print(e);
out.println(")");
}
}
/**
* Print the dependency tree for the given module with the given module root list.
*
* @param out the output stream to use
* @param identifier the identifier of the module to examine
* @param roots the module roots to search
* @deprecated Use {@link #print(PrintWriter, String, File...)} instead.
*/
@Deprecated
public static void print(PrintWriter out, ModuleIdentifier identifier, final File... roots) {
print(out, identifier.toString(), roots);
}
/**
* Print the dependency tree for the given module with the given module root list.
*
* @param out the output stream to use
* @param name the name of the module to examine
* @param roots the module roots to search
*/
public static void print(PrintWriter out, String name, final File... roots) {
out.print(name);
print(out, "", name, new FastCopyHashSet(), roots);
out.flush();
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FastCopyHashSet.java 0000664 0000000 0000000 00000037257 13417133242 0027243 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* A HashSet that is optimized for fast shallow copies. If the copy-ctor is
* passed another FastCopyHashSet, or clone is called on this set, the shallow
* copy can be performed using little more than a single array copy. In order to
* accomplish this, immutable objects must be used internally, so update
* operations result in slightly more object churn than HashSet
.
*
* Note: It is very important to use a smaller load factor than you normally
* would for HashSet, since the implementation is open-addressed with linear
* probing. With a 50% load-factor a get is expected to return in only 2 probes.
* However, a 90% load-factor is expected to return in around 50 probes.
*
* @author Jason T. Greene
* @author David M. Lloyd
*/
class FastCopyHashSet extends AbstractSet implements Set, Cloneable, Serializable {
/**
* Serialization ID
*/
private static final long serialVersionUID = 10929568968762L;
/**
* Same default as HashMap, must be a power of 2
*/
private static final int DEFAULT_CAPACITY = 64;
/**
* MAX_INT - 1
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 50%
*/
private static final float DEFAULT_LOAD_FACTOR = 0x0.5p0f;
/**
* The open-addressed table
*/
private transient E[] table;
/**
* The current number of key-value pairs
*/
private transient int size;
/**
* The next resize
*/
private transient int threshold;
/**
* The user defined load factor which defines when to resize
*/
private final float loadFactor;
/**
* Counter used to detect changes made outside of an iterator
*/
private transient int modCount;
/**
* Accumulated hash code
*/
private transient int hashCode;
FastCopyHashSet(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Can not have a negative size table!");
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (!(loadFactor > 0F && loadFactor <= 1F))
throw new IllegalArgumentException("Load factor must be greater than 0 and less than or equal to 1");
this.loadFactor = loadFactor;
init(initialCapacity, loadFactor);
}
FastCopyHashSet(Set extends E> set) {
if (set instanceof FastCopyHashSet) {
FastCopyHashSet extends E> fast = (FastCopyHashSet extends E>) set;
table = fast.table.clone();
loadFactor = fast.loadFactor;
size = fast.size;
threshold = fast.threshold;
hashCode = fast.hashCode;
} else {
loadFactor = DEFAULT_LOAD_FACTOR;
init(set.size(), loadFactor);
addAll(set);
}
}
@SuppressWarnings("unchecked")
private void init(int initialCapacity, float loadFactor) {
int c = 1;
while (c < initialCapacity) c <<= 1;
threshold = (int) (c * loadFactor);
// Include the load factor when sizing the table for the first time
if (initialCapacity > threshold && c < MAXIMUM_CAPACITY) {
c <<= 1;
threshold = (int) (c * loadFactor);
}
table = (E[]) new Object[c];
}
FastCopyHashSet(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
FastCopyHashSet() {
this(DEFAULT_CAPACITY);
}
private int nextIndex(int index, int length) {
index = (index >= length - 1) ? 0 : index + 1;
return index;
}
private static int index(int hashCode, int length) {
return hashCode & (length - 1);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object key) {
if (key == null) {
return false;
}
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
for (int start = index; ;) {
E e = table[index];
if (e == null)
return false;
if (key.equals(e))
return true;
index = nextIndex(index, length);
if (index == start) // Full table
return false;
}
}
public boolean add(E key) {
if (key == null) {
throw new IllegalArgumentException("key is null");
}
E[] table = this.table;
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
boolean f = false;
for (int start = index; ;) {
E e = table[index];
if (e == null)
break;
if (! f) {
f= true;
}
if (key.equals(e)) {
return false;
}
index = nextIndex(index, length);
if (index == start)
throw new IllegalStateException("Table is full!");
}
modCount++;
table[index] = key;
hashCode += key.hashCode();
if (++size >= threshold)
resize(length);
return true;
}
@SuppressWarnings("unchecked")
private void resize(int from) {
int newLength = from << 1;
// Can't get any bigger
if (newLength > MAXIMUM_CAPACITY || newLength <= from)
return;
E[] newTable = (E[]) new Object[newLength];
E[] old = table;
for (E e : old) {
if (e == null)
continue;
int index = index(e.hashCode(), newLength);
while (newTable[index] != null)
index = nextIndex(index, newLength);
newTable[index] = e;
}
threshold = (int) (loadFactor * newLength);
table = newTable;
}
public boolean addAll(Collection extends E> set) {
int size = set.size();
if (size == 0)
return false;
boolean changed = false;
for (E e : set) {
if (add(e)) {
changed = true;
}
}
return changed;
}
public boolean remove(Object key) {
E[] table = this.table;
int length = table.length;
int hash = key.hashCode();
int start = index(hash, length);
for (int index = start; ;) {
E e = table[index];
if (e == null)
return false;
if (key.equals(e)) {
table[index] = null;
hashCode -= hash;
relocate(index);
modCount++;
size--;
return true;
}
index = nextIndex(index, length);
if (index == start)
return false;
}
}
private void relocate(int start) {
E[] table = this.table;
int length = table.length;
int current = nextIndex(start, length);
for (; ;) {
E e = table[current];
if (e == null)
return;
// A Doug Lea variant of Knuth's Section 6.4 Algorithm R.
// This provides a non-recursive method of relocating
// entries to their optimal positions once a gap is created.
int prefer = index(e.hashCode(), length);
if ((current < prefer && (prefer <= start || start <= current))
|| (prefer <= start && start <= current)) {
table[start] = e;
table[current] = null;
start = current;
}
current = nextIndex(current, length);
}
}
public void clear() {
modCount++;
E[] table = this.table;
for (int i = 0; i < table.length; i++)
table[i] = null;
size = hashCode = 0;
}
@SuppressWarnings("unchecked")
public FastCopyHashSet clone() {
try {
FastCopyHashSet clone = (FastCopyHashSet) super.clone();
clone.table = table.clone();
return clone;
}
catch (CloneNotSupportedException e) {
// should never happen
throw new IllegalStateException(e);
}
}
public Iterator iterator() {
return new KeyIterator();
}
public void printDebugStats() {
int optimal = 0;
int total = 0;
int totalSkew = 0;
int maxSkew = 0;
for (int i = 0; i < table.length; i++) {
E e = table[i];
if (e != null) {
total++;
int target = index(e.hashCode(), table.length);
if (i == target)
optimal++;
else {
int skew = Math.abs(i - target);
if (skew > maxSkew) maxSkew = skew;
totalSkew += skew;
}
}
}
System.out.println(" Size: " + size);
System.out.println(" Real Size: " + total);
System.out.println(" Optimal: " + optimal + " (" + (float) optimal * 100 / total + "%)");
System.out.println(" Average Distance: " + ((float) totalSkew / (total - optimal)));
System.out.println(" Max Distance: " + maxSkew);
}
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
int size = s.readInt();
init(size, loadFactor);
for (int i = 0; i < size; i++) {
E key = (E) s.readObject();
putForCreate(key);
}
this.size = size;
}
@SuppressWarnings("unchecked")
private void putForCreate(E key) {
E[] table = this.table;
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
E e = table[index];
while (e != null) {
index = nextIndex(index, length);
e = table[index];
}
table[index] = key;
}
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeInt(size);
for (E e : table) {
if (e != null) {
s.writeObject(e);
}
}
}
public boolean containsAll(final Collection> c) {
final E[] table = this.table;
for (E e : table) {
if (e != null) {
if (! c.contains(e)) {
return false;
}
}
}
return true;
}
@SuppressWarnings("NonFinalFieldReferenceInEquals")
public boolean equals(final Object o) {
if (o == this)
return true;
if (! (o instanceof Set))
return false;
if (o instanceof FastCopyHashSet) {
final FastCopyHashSet> set = (FastCopyHashSet>) o;
if (hashCode != set.hashCode) {
return false;
}
if (table.length == set.table.length) {
return Arrays.equals(table, set.table);
}
}
Set> set = (Set>) o;
if (set.size() != size())
return false;
try {
return containsAll(set);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
@SuppressWarnings("NonFinalFieldReferencedInHashCode")
public int hashCode() {
return hashCode;
}
public Object[] getRawArray() {
return table;
}
private class KeyIterator implements Iterator {
private int next = 0;
private int expectedCount = modCount;
private int current = -1;
private boolean hasNext;
private E[] table = FastCopyHashSet.this.table;
public E next() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
if (!hasNext && !hasNext())
throw new NoSuchElementException();
current = next++;
hasNext = false;
return table[current];
}
public boolean hasNext() {
if (hasNext == true)
return true;
E[] table = this.table;
for (int i = next; i < table.length; i++) {
if (table[i] != null) {
next = i;
return hasNext = true;
}
}
next = table.length;
return false;
}
@SuppressWarnings("unchecked")
public void remove() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
int current = this.current;
int delete = current;
if (current == -1)
throw new IllegalStateException();
// Invalidate current (prevents multiple remove)
this.current = -1;
// Start were we relocate
next = delete;
E[] table = this.table;
if (table != FastCopyHashSet.this.table) {
FastCopyHashSet.this.remove(table[delete]);
table[delete] = null;
expectedCount = modCount;
return;
}
int length = table.length;
int i = delete;
table[delete] = null;
size--;
for (; ;) {
i = nextIndex(i, length);
E e = table[i];
if (e == null)
break;
int prefer = index(e.hashCode(), length);
if ((i < prefer && (prefer <= delete || delete <= i))
|| (prefer <= delete && delete <= i)) {
// Snapshot the unseen portion of the table if we have
// to relocate an entry that was already seen by this iterator
if (i < current && current <= delete && table == FastCopyHashSet.this.table) {
int remaining = length - current;
E[] newTable = (E[]) new Object[remaining];
System.arraycopy(table, current, newTable, 0, remaining);
// Replace iterator's table.
// Leave table local var pointing to the real table
this.table = newTable;
next = 0;
}
// Do the swap on the real table
table[delete] = e;
table[i] = null;
delete = i;
}
}
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FileSystemClassPathModuleFinder.java 0000775 0000000 0000000 00000033515 13417133242 0032414 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import static org.jboss.modules.Utils.DEPENDENCIES;
import static org.jboss.modules.Utils.EXPORT;
import static org.jboss.modules.Utils.MODULES_DIR;
import static org.jboss.modules.Utils.MODULE_VERSION;
import static org.jboss.modules.Utils.OPTIONAL;
import static org.jboss.modules.Utils.SERVICES;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.function.Supplier;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.jboss.modules.filter.MultiplePathFilterBuilder;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
import org.jboss.modules.xml.PermissionsXmlParser;
import org.jboss.modules.xml.XmlPullParserException;
/**
* A module finder which loads modules from individual JARs or directories on the file system, supporting the JAR specification headers
* as well as the extended {@code MANIFEST} headers supported by JBoss Modules. The JAR files or modules may in turn contain
* nested module repositories inside of their {@code modules} subdirectories. Modules in nested repositories are only visible
* to the module that contains them.
*
* @author David M. Lloyd
* @author Richard Opalka
*/
public class FileSystemClassPathModuleFinder implements ModuleFinder {
static final ModuleLoader EMPTY_MODULE_LOADER = new ModuleLoader();
static final SimpleSupplier EMPTY_MODULE_LOADER_SUPPLIER = new SimpleSupplier<>(EMPTY_MODULE_LOADER);
private final AccessControlContext context;
private final Supplier baseModuleLoaderSupplier;
private final Supplier extensionModuleLoaderSupplier;
private static final PathFilter NO_MODULES_DIR;
static {
final MultiplePathFilterBuilder builder = PathFilters.multiplePathFilterBuilder(true);
builder.addFilter(PathFilters.is(MODULES_DIR), false);
builder.addFilter(PathFilters.isChildOf(MODULES_DIR), false);
NO_MODULES_DIR = builder.create();
}
/**
* Construct a new instance.
*
* @param baseModuleLoader the module loader to use to load module dependencies from (must not be {@code null})
*/
public FileSystemClassPathModuleFinder(final ModuleLoader baseModuleLoader) {
this(baseModuleLoader, EMPTY_MODULE_LOADER_SUPPLIER);
}
/**
* Construct a new instance.
*
* @param baseModuleLoader the module loader to use to load module dependencies from (must not be {@code null})
* @param extensionModuleLoaderSupplier a supplier which yields a module loader for loading extensions (must not be {@code null})
*/
public FileSystemClassPathModuleFinder(final ModuleLoader baseModuleLoader, final Supplier extensionModuleLoaderSupplier) {
this(new SimpleSupplier<>(baseModuleLoader), extensionModuleLoaderSupplier);
if (baseModuleLoader == null) throw new IllegalArgumentException("baseModuleLoader is null");
}
/**
* Construct a new instance.
*
* @param baseModuleLoaderSupplier the supplier to supply a module loader for loading dependencies (must not be {@code null})
* @param extensionModuleLoaderSupplier a supplier which yields a module loader for loading extensions (must not be {@code null})
*/
public FileSystemClassPathModuleFinder(final Supplier baseModuleLoaderSupplier, final Supplier extensionModuleLoaderSupplier) {
if (baseModuleLoaderSupplier == null) throw new IllegalArgumentException("baseModuleLoaderSupplier is null");
this.baseModuleLoaderSupplier = baseModuleLoaderSupplier;
if (extensionModuleLoaderSupplier == null) throw new IllegalArgumentException("extensionModuleLoaderSupplier is null");
this.extensionModuleLoaderSupplier = extensionModuleLoaderSupplier;
context = AccessController.getContext();
}
public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) throws ModuleLoadException {
final Path path = Paths.get(name);
if (! path.isAbsolute()) {
return null;
}
final Path normalizedPath = path.normalize();
if (! path.equals(normalizedPath)) {
return null;
}
try {
final Manifest manifest;
final String fileName = path.toString();
final ModuleSpec.Builder builder = ModuleSpec.build(fileName);
final ResourceLoader resourceLoader;
final ModuleLoader fatModuleLoader;
final ModuleLoader baseModuleLoader = baseModuleLoaderSupplier.get();
if (Files.isDirectory(path)) {
manifest = new Manifest();
final Path manifestPath = path.resolve("META-INF/MANIFEST.MF");
if (Files.exists(manifestPath)) try {
try (InputStream stream = Files.newInputStream(manifestPath, StandardOpenOption.READ)) {
manifest.read(stream);
}
} catch (NoSuchFileException | FileNotFoundException ignored) {
} catch (IOException e) {
throw new ModuleLoadException("Failed to load MANIFEST from " + path, e);
}
resourceLoader = new PathResourceLoader(fileName, path, context);
fatModuleLoader = new DelegatingModuleLoader(baseModuleLoader, new LocalModuleFinder(new File[]{ path.resolve(MODULES_DIR).toFile() }));
} else {
// assume some kind of JAR file
final JarFile jarFile = JDKSpecific.getJarFile(path.toFile(), true);
try {
try {
manifest = jarFile.getManifest();
} catch (IOException e) {
throw new ModuleLoadException("Failed to load MANIFEST from " + path, e);
}
resourceLoader = new JarFileResourceLoader(fileName, jarFile);
} catch (Throwable t) {
try {
jarFile.close();
} catch (Throwable e2) {
e2.addSuppressed(t);
throw e2;
}
throw t;
}
fatModuleLoader = new DelegatingModuleLoader(baseModuleLoader, new ResourceLoaderModuleFinder(resourceLoader));
}
// now build the module specification from the manifest information
try {
addSelfContent(builder, resourceLoader);
addSelfDependency(builder);
final Attributes mainAttributes = manifest.getMainAttributes();
setMainClass(builder, mainAttributes);
addClassPathDependencies(builder, delegateLoader, path, mainAttributes);
final ModuleLoader extensionModuleLoader = extensionModuleLoaderSupplier.get();
addExtensionDependencies(builder, mainAttributes, extensionModuleLoader);
addModuleDependencies(builder, fatModuleLoader, mainAttributes);
setModuleVersion(builder, mainAttributes);
addSystemDependencies(builder);
addPermissions(builder, resourceLoader, delegateLoader);
} catch (Throwable t) {
resourceLoader.close();
throw t;
}
return builder.create();
} catch (IOException e) {
throw new ModuleLoadException(e);
}
}
void addPermissions(final ModuleSpec.Builder builder, final ResourceLoader resourceLoader, final ModuleLoader moduleLoader) {
final Resource resource = resourceLoader.getResource("META-INF/permissions.xml");
if (resource != null) {
try {
try (InputStream stream = resource.openStream()) {
builder.setPermissionCollection(PermissionsXmlParser.parsePermissionsXml(stream, moduleLoader, builder.getName()));
}
} catch (XmlPullParserException | IOException ignored) {
}
}
}
void addSystemDependencies(final ModuleSpec.Builder builder) {
builder.addDependency(new LocalDependencySpecBuilder()
.setLocalLoader(ClassLoaderLocalLoader.SYSTEM)
.setLoaderPaths(JDKPaths.JDK)
.build());
}
void addModuleDependencies(final ModuleSpec.Builder builder, final ModuleLoader fatModuleLoader, final Attributes mainAttributes) {
final String dependencies = mainAttributes.getValue(DEPENDENCIES);
final String[] dependencyEntries = dependencies == null ? Utils.NO_STRINGS : dependencies.split("\\s*,\\s*");
for (String dependencyEntry : dependencyEntries) {
boolean optional = false;
boolean export = false;
boolean services = false;
dependencyEntry = dependencyEntry.trim();
if (! dependencyEntry.isEmpty()) {
String[] fields = dependencyEntry.split("\\s+");
if (fields.length < 1) {
continue;
}
String moduleName = fields[0];
for (int i = 1; i < fields.length; i++) {
String field = fields[i];
if (field.equals(OPTIONAL)) {
optional = true;
} else if (field.equals(EXPORT)) {
export = true;
} else if (field.equals(SERVICES)) {
services = true;
}
// else ignored
}
builder.addDependency(new ModuleDependencySpecBuilder()
.setImportServices(services)
.setExport(export)
.setModuleLoader(fatModuleLoader)
.setName(moduleName)
.setOptional(optional)
.build());
}
}
}
void setModuleVersion(final ModuleSpec.Builder builder, final Attributes mainAttributes) {
final String versionString = mainAttributes.getValue(MODULE_VERSION);
if (versionString != null) {
builder.setVersion(Version.parse(versionString));
}
}
void addExtensionDependencies(final ModuleSpec.Builder builder, final Attributes mainAttributes, final ModuleLoader extensionModuleLoader) {
final String extensionList = mainAttributes.getValue(Attributes.Name.EXTENSION_LIST);
final String[] extensionListEntries = extensionList == null ? Utils.NO_STRINGS : extensionList.split("\\s+");
for (String entry : extensionListEntries) {
if (! entry.isEmpty()) {
builder.addDependency(new ModuleDependencySpecBuilder()
.setImportFilter(PathFilters.acceptAll())
.setModuleLoader(extensionModuleLoader)
.setName(entry)
.setOptional(true)
.build());
}
}
}
void addClassPathDependencies(final ModuleSpec.Builder builder, final ModuleLoader moduleLoader, final Path path, final Attributes mainAttributes) {
final String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
final String[] classPathEntries = classPath == null ? Utils.NO_STRINGS : classPath.split("\\s+");
for (String entry : classPathEntries) {
if (! entry.isEmpty()) {
final URI uri;
try {
uri = new URI(entry);
} catch (URISyntaxException e) {
// ignore invalid class path entries
continue;
}
final Path depPath = path.resolveSibling(Paths.get(uri)).normalize();
// simple dependency; class path deps are always optional
builder.addDependency(new ModuleDependencySpecBuilder()
.setImportFilter(PathFilters.acceptAll())
.setModuleLoader(moduleLoader)
.setName(depPath.toString())
.setOptional(true)
.build());
}
}
}
void setMainClass(final ModuleSpec.Builder builder, final Attributes mainAttributes) {
final String mainClass = mainAttributes.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
builder.setMainClass(mainClass);
}
}
void addSelfDependency(final ModuleSpec.Builder builder) {
// add our own dependency
builder.addDependency(DependencySpec.OWN_DEPENDENCY);
}
void addSelfContent(final ModuleSpec.Builder builder, final ResourceLoader resourceLoader) {
// add our own content
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader, NO_MODULES_DIR));
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FilteredIterableLocalLoader.java 0000664 0000000 0000000 00000004307 13417133242 0031531 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* @author David M. Lloyd
*/
class FilteredIterableLocalLoader implements IterableLocalLoader {
private final ClassFilter classFilter;
private final IterableLocalLoader originalLoader;
private final PathFilter resourcePathFilter;
FilteredIterableLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) {
this.classFilter = classFilter;
this.originalLoader = originalLoader;
this.resourcePathFilter = resourcePathFilter;
}
public Class> loadClassLocal(final String name, final boolean resolve) {
return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null;
}
public Package loadPackageLocal(final String name) {
return originalLoader.loadPackageLocal(name);
}
public List loadResourceLocal(final String name) {
return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList();
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
return PathFilters.filtered(resourcePathFilter, originalLoader.iterateResources(startPath, recursive));
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FilteredIterableResourceLoader.java 0000664 0000000 0000000 00000005150 13417133242 0032263 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Iterator;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
final class FilteredIterableResourceLoader implements IterableResourceLoader {
private final PathFilter filter;
private final IterableResourceLoader loader;
FilteredIterableResourceLoader(final PathFilter filter, final IterableResourceLoader loader) {
this.filter = filter;
this.loader = loader;
}
@Deprecated
public String getRootName() {
return loader.getRootName();
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName));
return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null;
}
public PackageSpec getPackageSpec(final String name) throws IOException {
return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Resource getResource(final String name) {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name));
return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null;
}
public String getLibrary(final String name) {
return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Collection getPaths() {
return loader.getPaths();
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
return PathFilters.filtered(filter, loader.iterateResources(PathUtils.relativize(PathUtils.canonicalize(startPath)), recursive));
}
public void close() {
loader.close();
}
public URI getLocation() {
return loader.getLocation();
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FilteredLocalLoader.java 0000664 0000000 0000000 00000003576 13417133242 0030070 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.List;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
/**
* @author David M. Lloyd
*/
class FilteredLocalLoader implements LocalLoader {
private final ClassFilter classFilter;
private final LocalLoader originalLoader;
private final PathFilter resourcePathFilter;
FilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) {
this.classFilter = classFilter;
this.originalLoader = originalLoader;
this.resourcePathFilter = resourcePathFilter;
}
public Class> loadClassLocal(final String name, final boolean resolve) {
return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null;
}
public Package loadPackageLocal(final String name) {
return originalLoader.loadPackageLocal(name);
}
public List loadResourceLocal(final String name) {
return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList();
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/FilteredResourceLoader.java 0000664 0000000 0000000 00000004625 13417133242 0030621 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import org.jboss.modules.filter.PathFilter;
/**
* @author David M. Lloyd
* @author Richard Opalka
*/
final class FilteredResourceLoader implements ResourceLoader {
private final PathFilter filter;
private final ResourceLoader loader;
FilteredResourceLoader(final PathFilter filter, final ResourceLoader loader) {
this.filter = filter;
this.loader = loader;
}
@Deprecated
public String getRootName() {
return loader.getRootName();
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName));
return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null;
}
public PackageSpec getPackageSpec(final String name) throws IOException {
return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Resource getResource(final String name) {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name));
return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null;
}
public String getLibrary(final String name) {
return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Collection getPaths() {
return loader.getPaths();
}
public void close() {
loader.close();
}
public URI getLocation() {
return loader.getLocation();
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/GetURLConnectionAction.java 0000664 0000000 0000000 00000002302 13417133242 0030472 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.security.PrivilegedExceptionAction;
/**
*/
final class GetURLConnectionAction implements PrivilegedExceptionAction {
private final URL url;
GetURLConnectionAction(final URL url) {
this.url = url;
}
public URLConnection run() throws IOException {
final URLConnection c = url.openConnection();
c.connect();
return c;
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/IterableLocalLoader.java 0000664 0000000 0000000 00000003101 13417133242 0030041 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Iterator;
/**
* A local loader which can enumerate its contents.
*
* @author David M. Lloyd
*/
public interface IterableLocalLoader extends LocalLoader {
/**
* Enumerate all the resources under the given path. The given path name is relative to the root
* of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed.
* If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}.
*
* @param startPath the path to search under
* @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path
* @return the resource iterator (possibly empty)
*/
Iterator iterateResources(String startPath, boolean recursive);
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/IterableModuleFinder.java 0000664 0000000 0000000 00000004550 13417133242 0030246 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.Iterator;
/**
* A module finder which is iterable.
*
* @author David M. Lloyd
*/
public interface IterableModuleFinder extends ModuleFinder {
/**
* This method returns an empty iterator and should not be used by new code.
*
* @param baseIdentifier the identifier to start with, or {@code null} to iterate all modules
* @param recursive {@code true} to find recursively nested modules, {@code false} to only find immediately nested
* modules
* @return an iterator for the modules in this module finder
* @deprecated Use {@link #iterateModules(String, boolean)} instead.
*/
default Iterator iterateModules(ModuleIdentifier baseIdentifier, boolean recursive) {
return Collections.emptyIterator();
}
/**
* Iterate the modules which can be located via this module finder.
*
* @param baseName the identifier to start with, or {@code null} to iterate all modules; ignored if this module
* loader does not have a concept of nested modules
* @param recursive {@code true} to find recursively nested modules, {@code false} to only find immediately nested
* modules; ignored if this module finder does not have a concept of nested modules
* @return an iterator for the modules in this module finder
*/
default Iterator iterateModules(String baseName, boolean recursive) {
return IteratorUtils.transformingIterator(iterateModules(baseName == null ? null : ModuleIdentifier.fromString(baseName), recursive), ModuleIdentifier::toString);
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/IterableResourceLoader.java 0000664 0000000 0000000 00000003131 13417133242 0030601 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Iterator;
/**
* A resource loader which has the ability to enumerate its contents.
*
* @author David M. Lloyd
*/
public interface IterableResourceLoader extends ResourceLoader {
/**
* Enumerate all the resources under the given path. The given path name is relative to the root
* of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed.
* If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}.
*
* @param startPath the path to search under
* @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path
* @return the resource iterator (possibly empty)
*/
Iterator iterateResources(String startPath, boolean recursive);
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/IteratorUtils.java 0000664 0000000 0000000 00000002431 13417133242 0027027 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2016 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Iterator;
import java.util.function.Function;
/**
* @author David M. Lloyd
*/
final class IteratorUtils {
private IteratorUtils() {
}
public static Iterator transformingIterator(Iterator original, Function translator) {
return new Iterator() {
public boolean hasNext() {
return original.hasNext();
}
public U next() {
return translator.apply(original.next());
}
};
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JDKModuleFinder.java 0000664 0000000 0000000 00000020440 13417133242 0027123 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.jboss.modules.filter.PathFilters;
/**
* A module finder which finds a standard JDK module, a module on the JDK module path, or the special module
* {@code org.jboss.modules}.
*/
public final class JDKModuleFinder implements IterableModuleFinder {
private final ConcurrentHashMap modules = new ConcurrentHashMap<>();
private final List moduleNames;
static final class SEDeps {
static final List javaSeDeps;
static {
List deps = new ArrayList<>();
for (String dep : Arrays.asList(
"java.compiler",
"java.datatransfer",
"java.desktop",
"java.instrument",
"java.logging",
"java.management",
"java.management.rmi",
"java.naming",
"java.prefs",
"java.rmi",
"java.scripting",
"java.security.jgss",
"java.security.sasl",
"java.sql",
"java.sql.rowset",
"java.xml",
"java.xml.crypto"
)) {
deps.add(new ModuleDependencySpecBuilder().setName(dep).setExport(true).build());
}
javaSeDeps = deps;
}
}
private static final JDKModuleFinder INSTANCE = new JDKModuleFinder();
private JDKModuleFinder() {
moduleNames = Collections.unmodifiableList(Arrays.asList(
"java.sql",
"java.base",
"java.compiler",
"java.datatransfer",
"java.desktop",
"java.instrument",
"java.jnlp",
"java.logging",
"java.management",
"java.management.rmi",
"java.naming",
"java.prefs",
"java.rmi",
"java.scripting",
"java.security.jgss",
"java.security.sasl",
"java.smartcardio",
"java.sql.rowset",
"java.xml",
"java.xml.crypto",
"javafx.base",
"javafx.controls",
"javafx.fxml",
"javafx.graphics",
"javafx.media",
"javafx.swing",
"javafx.web",
"jdk.accessibility",
"jdk.attach",
"jdk.compiler",
"jdk.httpserver",
"jdk.jartool",
"jdk.javadoc",
"jdk.jconsole",
"jdk.jdi",
"jdk.jfr",
"jdk.jsobject",
"jdk.management",
"jdk.management.cmm",
"jdk.management.jfr",
"jdk.management.resource",
"jdk.net",
"jdk.plugin.dom",
"jdk.scripting.nashorn",
"jdk.sctp",
"jdk.security.auth",
"jdk.security.jgss",
"jdk.unsupported",
"jdk.xml.dom",
"org.jboss.modules"
));
}
/**
* Get the singleton instance.
*
* @return the singleton instance
*/
public static JDKModuleFinder getInstance() {
return INSTANCE;
}
public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) throws ModuleLoadException {
FutureSpec futureSpec = modules.get(name);
if (futureSpec == null) {
final FutureSpec appearing = modules.putIfAbsent(name, futureSpec = new FutureSpec());
if (appearing != null) {
futureSpec = appearing;
} else {
switch (name) {
case "java.se": {
final ModuleSpec.Builder builder = ModuleSpec.build("java.se", false);
for (DependencySpec dep : SEDeps.javaSeDeps) {
builder.addDependency(dep);
}
futureSpec.setModuleSpec(builder.create());
break;
}
default: {
final ModuleSpec moduleSpec = loadModuleSpec(name);
futureSpec.setModuleSpec(moduleSpec);
if (moduleSpec == null) {
modules.remove(name, futureSpec);
}
break;
}
}
}
}
return futureSpec.getModuleSpec();
}
public Iterator iterateModules(final String baseName, final boolean recursive) {
return moduleNames.iterator();
}
private ModuleSpec loadModuleSpec(final String name) throws ModuleLoadException {
Set paths = new HashSet<>();
InputStream is = getClass().getResourceAsStream("/jdk-module-paths/" + name);
if (is == null) {
return null;
}
try (InputStream tmp = is) {
try (InputStreamReader isr = new InputStreamReader(tmp, StandardCharsets.UTF_8)) {
try (BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
String trimmed = line.trim();
if (trimmed.isEmpty() || trimmed.startsWith("#")) {
continue;
}
paths.add(trimmed);
}
}
}
} catch (IOException e) {
throw new ModuleLoadException(e);
}
final ModuleSpec.Builder builder = ModuleSpec.build(name, false);
final LocalDependencySpecBuilder dependencySpecBuilder = new LocalDependencySpecBuilder();
dependencySpecBuilder.setLoaderPaths(paths);
dependencySpecBuilder.setExport(true);
dependencySpecBuilder.setImportFilter(PathFilters.acceptAll());
dependencySpecBuilder.setLocalLoader(JDKSpecific.getSystemLocalLoader());
builder.addDependency(dependencySpecBuilder.build());
return builder.create();
}
public String toString() {
return "JDK Module Finder";
}
static final class FutureSpec {
private static final ModuleSpec MARKER = ModuleSpec.build("dummy").create();
private volatile ModuleSpec moduleSpec = MARKER;
FutureSpec() {
}
void setModuleSpec(final ModuleSpec moduleSpec) {
synchronized (this) {
this.moduleSpec = moduleSpec;
notifyAll();
}
}
public ModuleSpec getModuleSpec() {
ModuleSpec moduleSpec = this.moduleSpec;
if (moduleSpec == MARKER) {
synchronized (this) {
moduleSpec = this.moduleSpec;
boolean intr = false;
try {
while (moduleSpec == MARKER) try {
wait();
moduleSpec = this.moduleSpec;
} catch (InterruptedException e) {
intr = true;
}
} finally {
if (intr) Thread.currentThread().interrupt();
}
}
}
return moduleSpec;
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JDKPaths.java 0000664 0000000 0000000 00000010140 13417133242 0025621 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* A utility class which maintains the set of JDK paths. Makes certain assumptions about the disposition of the
* class loader used to load JBoss Modules; thus this class should only be used when booted up via the "-jar" or "-cp"
* switches.
*
* @author David M. Lloyd
* @author Richard Opalka
*/
final class JDKPaths {
static final Set JDK;
static {
final Set pathSet = JDKSpecific.getJDKPaths();
if (pathSet.size() == 0) throw new IllegalStateException("Something went wrong with system paths set up");
JDK = Collections.unmodifiableSet(pathSet);
}
private JDKPaths() {
}
static void processJar(final Set pathSet, final File file) throws IOException {
try (final ZipFile zipFile = new ZipFile(file)) {
final Enumeration extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
final String name = entry.getName();
final int lastSlash = name.lastIndexOf('/');
if (lastSlash != -1) {
pathSet.add(name.substring(0, lastSlash));
}
}
}
}
static void processClassPathItem(final String classPath, final Set jarSet, final Set pathSet) {
if (classPath == null) return;
int s = 0, e;
do {
e = classPath.indexOf(File.pathSeparatorChar, s);
String item = e == -1 ? classPath.substring(s) : classPath.substring(s, e);
if (! jarSet.contains(item)) {
final File file = new File(item);
if (file.isDirectory()) {
processDirectory(pathSet, file);
} else {
try {
processJar(pathSet, file);
} catch (IOException ex) {
// ignore
}
}
}
s = e + 1;
} while (e != -1);
}
static void processDirectory(final Set pathSet, final File file) {
for (File entry : file.listFiles()) {
if (entry.isDirectory()) {
processDirectory1(pathSet, entry, file.getPath());
} else {
final String parent = entry.getParent();
if (parent != null) pathSet.add(parent);
}
}
}
private static void processDirectory1(final Set pathSet, final File file, final String pathBase) {
for (File entry : file.listFiles()) {
if (entry.isDirectory()) {
processDirectory1(pathSet, entry, pathBase);
} else {
String packagePath = entry.getParent();
if (packagePath != null) {
packagePath = packagePath.substring(pathBase.length()).replace('\\', '/');
if(packagePath.startsWith("/")) {
packagePath = packagePath.substring(1);
}
pathSet.add(packagePath);
}
}
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JDKSpecific.java 0000664 0000000 0000000 00000016364 13417133242 0026305 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2016 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.jar.JarFile;
import sun.reflect.Reflection;
/**
* JDK-specific classes which are replaced for different JDK major versions. This one is for Java 8 only.
*
* @author David M. Lloyd
* @author Richard Opalka
*/
final class JDKSpecific {
// === private fields and data ===
private static Hack hack = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Hack run() {
return new Hack();
}
});
private static final MethodHandle getPackageMH;
private static final boolean hasGetCallerClass;
private static final int callerOffset;
static {
try {
getPackageMH = MethodHandles.lookup().unreflect(AccessController.doPrivileged(new PrivilegedAction() {
public Method run() {
for (Method method : ClassLoader.class.getDeclaredMethods()) {
if (method.getName().equals("getPackage")) {
Class>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1 && parameterTypes[0] == String.class) {
method.setAccessible(true);
return method;
}
}
}
throw new IllegalStateException("No getPackage method found on ClassLoader");
}
}));
} catch (IllegalAccessException e) {
final IllegalAccessError error = new IllegalAccessError(e.getMessage());
error.setStackTrace(e.getStackTrace());
throw error;
}
boolean result = false;
int offset = 0;
try {
//noinspection deprecation
result = Reflection.getCallerClass(1) == JDKSpecific.class || Reflection.getCallerClass(2) == JDKSpecific.class;
//noinspection deprecation
offset = Reflection.getCallerClass(1) == Reflection.class ? 2 : 1;
} catch (Throwable ignored) {}
hasGetCallerClass = result;
callerOffset = offset;
}
// === the actual JDK-specific API ===
static JarFile getJarFile(final File name, final boolean verify) throws IOException {
return new JarFile(name, verify);
}
static Class> getCallingUserClass() {
// 0 == this class
// 1 == immediate caller in jboss-modules
// 2 == user caller
Class>[] stack = hack.getClassContext();
int i = 3;
while (stack[i] == stack[2]) {
// skip nested calls front the same class
if (++i >= stack.length)
return null;
}
return stack[i];
}
static Class> getCallingClass() {
// 0 == this class
// 1 == immediate caller in jboss-modules
// 2 == user caller
if (hasGetCallerClass) {
return Reflection.getCallerClass(2 + callerOffset);
} else {
return hack.getClassContext()[2 + callerOffset];
}
}
static boolean isParallelCapable(ConcurrentClassLoader cl) {
return ConcurrentClassLoader.getLockForClass(cl, "$TEST$") != cl;
}
static Package getPackage(ClassLoader cl, String packageName) {
try {
return (Package) getPackageMH.invoke(cl, packageName);
} catch (RuntimeException | Error e2) {
throw e2;
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
static Set getJDKPaths() {
final Set pathSet = new FastCopyHashSet<>(1024);
final Set jarSet = new FastCopyHashSet<>(1024);
final String sunBootClassPath = AccessController.doPrivileged(new PropertyReadAction("sun.boot.class.path"));
final String javaClassPath = AccessController.doPrivileged(new PropertyReadAction("java.class.path"));
JDKPaths.processClassPathItem(sunBootClassPath, jarSet, pathSet);
JDKPaths.processClassPathItem(javaClassPath, jarSet, pathSet);
pathSet.add("org/jboss/modules");
pathSet.add("org/jboss/modules/filter");
pathSet.add("org/jboss/modules/log");
pathSet.add("org/jboss/modules/management");
pathSet.add("org/jboss/modules/ref");
return Collections.unmodifiableSet(pathSet);
}
static LocalLoader getSystemLocalLoader() {
return new ClassLoaderLocalLoader(getPlatformClassLoader());
}
static ClassLoader getPlatformClassLoader() {
return JDKSpecific.class.getClassLoader();
}
static URL getSystemResource(final String name) {
final ClassLoader classLoader = getPlatformClassLoader();
return classLoader != null ? classLoader.getResource(name) : ClassLoader.getSystemResource(name);
}
static Enumeration getSystemResources(final String name) throws IOException {
final ClassLoader classLoader = getPlatformClassLoader();
return classLoader != null ? classLoader.getResources(name) : ClassLoader.getSystemResources(name);
}
static InputStream getSystemResourceAsStream(final String name) {
final ClassLoader classLoader = getPlatformClassLoader();
return classLoader != null ? classLoader.getResourceAsStream(name) : ClassLoader.getSystemResourceAsStream(name);
}
static Class> getSystemClass(final ConcurrentClassLoader caller, final String className) throws ClassNotFoundException {
final ClassLoader platformClassLoader = JDKSpecific.getPlatformClassLoader();
return platformClassLoader != null ? platformClassLoader.loadClass(className) : caller.findSystemClassInternal(className);
}
static void addInternalPackages(final List list) {
list.add("sun.reflect.");
list.add("jdk.internal.reflect.");
}
// === nested util stuff, non-API ===
static final class Hack extends SecurityManager {
@Override
protected Class>[] getClassContext() {
return super.getClassContext();
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JLIClassTransformer.java 0000664 0000000 0000000 00000004552 13417133242 0030052 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.nio.ByteBuffer;
import java.security.ProtectionDomain;
/**
* A wrapper around a {@link ClassFileTransformer}.
*/
public final class JLIClassTransformer implements ClassTransformer {
private final ClassFileTransformer transformer;
/**
* Construct a new instance.
*
* @param transformer the delegate transformer (must not be {@code null})
*/
public JLIClassTransformer(final ClassFileTransformer transformer) {
if (transformer == null) throw new IllegalArgumentException("transformer is null");
this.transformer = transformer;
}
public ByteBuffer transform(final ClassLoader loader, final String className, final ProtectionDomain protectionDomain, final ByteBuffer classBytes) throws IllegalArgumentException {
final int position = classBytes.position();
final int limit = classBytes.limit();
final byte[] bytes;
final byte[] result;
if (classBytes.hasArray() && classBytes.arrayOffset() == 0 && position == 0 && limit == classBytes.capacity()) {
bytes = classBytes.array();
} else {
bytes = new byte[limit - position];
classBytes.get(bytes);
classBytes.position(position);
}
try {
result = transformer.transform(loader, className, null, protectionDomain, bytes);
} catch (IllegalClassFormatException e) {
throw new IllegalArgumentException(e);
}
return result == null || result == bytes ? classBytes : ByteBuffer.wrap(result);
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JarEntryResource.java 0000664 0000000 0000000 00000004115 13417133242 0027464 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
/**
* @author David M. Lloyd
* @author Richard Opalka
*/
final class JarEntryResource implements Resource {
private final JarFile jarFile;
private final String relativePath;
private final String entryName;
private final URL resourceURL;
JarEntryResource(final JarFile jarFile, final String name, final String relativePath, final URL resourceURL) {
this.jarFile = jarFile;
this.relativePath = relativePath;
this.entryName = relativePath == null ? name : name.substring(relativePath.length() + 1);
this.resourceURL = resourceURL;
}
public String getName() {
return entryName;
}
public URL getURL() {
return resourceURL;
}
public InputStream openStream() throws IOException {
return jarFile.getInputStream(getEntry());
}
public long getSize() {
final long size = getEntry().getSize();
return size == -1 ? 0 : size;
}
private ZipEntry getEntry() {
final String relativePath = this.relativePath;
return relativePath == null ? jarFile.getEntry(entryName) : jarFile.getEntry(relativePath + "/" + entryName);
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JarFileResourceLoader.java 0000664 0000000 0000000 00000045630 13417133242 0030400 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static java.security.AccessController.doPrivileged;
/**
*
* @author David M. Lloyd
* @author Thomas.Diesler@jboss.com
* @author Richard Opalka
*/
final class JarFileResourceLoader extends AbstractResourceLoader implements IterableResourceLoader {
private static final String INDEX_FILE = "META-INF/PATHS.LIST";
private final JarFile jarFile;
private final String rootName;
private final URL rootUrl;
private final String relativePath;
private final File fileOfJar;
private volatile List directory;
// protected by {@code this}
private final Map codeSources = new HashMap<>();
JarFileResourceLoader(final String rootName, final JarFile jarFile) {
this(rootName, jarFile, null);
}
JarFileResourceLoader(final String rootName, final JarFile jarFile, final String relativePath) {
if (jarFile == null) {
throw new IllegalArgumentException("jarFile is null");
}
if (rootName == null) {
throw new IllegalArgumentException("rootName is null");
}
fileOfJar = new File(jarFile.getName());
this.jarFile = jarFile;
this.rootName = rootName;
String realPath = relativePath == null ? null : PathUtils.canonicalize(relativePath);
if (realPath != null && realPath.endsWith("/")) realPath = realPath.substring(0, realPath.length() - 1);
this.relativePath = realPath;
try {
rootUrl = getJarURI(fileOfJar.toURI(), realPath).toURL();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
}
}
private static URI getJarURI(final URI original, final String nestedPath) throws URISyntaxException {
final StringBuilder b = new StringBuilder();
b.append("file:");
assert original.getScheme().equals("file");
final String path = original.getPath();
assert path != null;
final String host = original.getHost();
if (host != null) {
final String userInfo = original.getRawUserInfo();
b.append("//");
if (userInfo != null) {
b.append(userInfo).append('@');
}
b.append(host);
}
b.append(path).append("!/");
if (nestedPath != null) {
b.append(nestedPath);
}
return new URI("jar", b.toString(), null);
}
public String getRootName() {
return rootName;
}
public synchronized ClassSpec getClassSpec(final String fileName) throws IOException {
final ClassSpec spec = new ClassSpec();
final JarEntry entry = getJarEntry(fileName);
if (entry == null) {
// no such entry
return null;
}
final long size = entry.getSize();
try (final InputStream is = jarFile.getInputStream(entry)) {
if (size == -1) {
// size unknown
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] buf = new byte[16384];
int res;
while ((res = is.read(buf)) > 0) {
baos.write(buf, 0, res);
}
// done
CodeSource codeSource = createCodeSource(entry);
baos.close();
is.close();
spec.setBytes(baos.toByteArray());
spec.setCodeSource(codeSource);
return spec;
} else if (size <= (long) Integer.MAX_VALUE) {
final int castSize = (int) size;
byte[] bytes = new byte[castSize];
int a = 0, res;
while ((res = is.read(bytes, a, castSize - a)) > 0) {
a += res;
}
// consume remainder so that cert check doesn't fail in case of wonky JARs
while (is.read() != -1) {
//
}
// done
CodeSource codeSource = createCodeSource(entry);
is.close();
spec.setBytes(bytes);
spec.setCodeSource(codeSource);
return spec;
} else {
throw new IOException("Resource is too large to be a valid class file");
}
}
}
// this MUST only be called after the input stream is fully read (see MODULES-201)
private CodeSource createCodeSource(final JarEntry entry) {
final CodeSigner[] entryCodeSigners = entry.getCodeSigners();
final CodeSigners codeSigners = entryCodeSigners == null || entryCodeSigners.length == 0 ? EMPTY_CODE_SIGNERS : new CodeSigners(entryCodeSigners);
CodeSource codeSource = codeSources.get(codeSigners);
if (codeSource == null) {
codeSources.put(codeSigners, codeSource = new CodeSource(rootUrl, entryCodeSigners));
}
return codeSource;
}
private JarEntry getJarEntry(final String fileName) {
return relativePath == null ? jarFile.getJarEntry(fileName) : jarFile.getJarEntry(relativePath + "/" + fileName);
}
public PackageSpec getPackageSpec(final String name) throws IOException {
final Manifest manifest;
if (relativePath == null) {
manifest = jarFile.getManifest();
} else {
JarEntry jarEntry = getJarEntry("META-INF/MANIFEST.MF");
if (jarEntry == null) {
manifest = null;
} else {
try (final InputStream inputStream = jarFile.getInputStream(jarEntry)) {
manifest = new Manifest(inputStream);
}
}
}
return getPackageSpec(name, manifest, rootUrl);
}
public String getLibrary(final String name) {
// JARs cannot have libraries in them
return null;
}
public Resource getResource(String name) {
try {
final JarFile jarFile = this.jarFile;
name = PathUtils.canonicalize(PathUtils.relativize(name));
final JarEntry entry = getJarEntry(name);
if (entry == null) {
return null;
}
final URI uri;
try {
File absoluteFile = new File(jarFile.getName()).getAbsoluteFile();
String path = absoluteFile.getPath();
path = PathUtils.canonicalize(path);
if (File.separatorChar != '/') {
// optimizes away on platforms with /
path = path.replace(File.separatorChar, '/');
}
if (PathUtils.isRelative(path)) {
// should not be possible, but the JDK thinks this might happen sometimes..?
path = "/" + path;
}
if (path.startsWith("//")) {
// UNC path URIs have loads of leading slashes
path = "//" + path;
}
uri = new URI("file", null, path, null);
} catch (URISyntaxException x) {
throw new IllegalStateException(x);
}
final URL url = new URL(null, getJarURI(uri, entry.getName()).toString(), (URLStreamHandler) null);
try {
doPrivileged(new GetURLConnectionAction(url));
} catch (PrivilegedActionException e) {
// ignored; the user might not even ask for the URL
}
return new JarEntryResource(jarFile, entry.getName(), relativePath, url);
} catch (MalformedURLException e) {
// must be invalid...? (todo: check this out)
return null;
} catch (URISyntaxException e) {
// must be invalid...? (todo: check this out)
return null;
}
}
public Iterator iterateResources(String startPath, final boolean recursive) {
if (relativePath != null) startPath = startPath.equals("") ? relativePath : relativePath + "/" + startPath;
final String startName = PathUtils.canonicalize(PathUtils.relativize(startPath));
List directory = this.directory;
if (directory == null) {
synchronized (jarFile) {
directory = this.directory;
if (directory == null) {
directory = new ArrayList<>();
final Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry jarEntry = entries.nextElement();
if (! jarEntry.isDirectory()) {
directory.add(jarEntry.getName());
}
}
this.directory = directory;
}
}
}
final Iterator iterator = directory.iterator();
return new Iterator() {
private Resource next;
public boolean hasNext() {
while (next == null) {
if (! iterator.hasNext()) {
return false;
}
final String name = iterator.next();
if ((recursive ? PathUtils.isChild(startName, name) : PathUtils.isDirectChild(startName, name))) {
try {
next = new JarEntryResource(jarFile, name, relativePath, getJarURI(new File(jarFile.getName()).toURI(), name).toURL());
} catch (Exception ignored) {
}
}
}
return true;
}
public Resource next() {
if (! hasNext()) {
throw new NoSuchElementException();
}
try {
return next;
} finally {
next = null;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Collection getPaths() {
final Collection index = new HashSet();
index.add("");
String relativePath = this.relativePath;
// First check for an external index
final JarFile jarFile = this.jarFile;
// Next check for an internal index
JarEntry listEntry = jarFile.getJarEntry(INDEX_FILE);
if (listEntry != null) {
try {
return readIndex(jarFile.getInputStream(listEntry), index, relativePath);
} catch (IOException e) {
index.clear();
}
}
// Next just read the JAR
extractJarPaths(jarFile, relativePath, index);
return index;
}
@Override
public void close() {
try {
super.close();
} finally {
try {
jarFile.close();
} catch (IOException e) {
// ignored
}
}
}
public URI getLocation() {
try {
return getJarURI(fileOfJar.toURI(), "");
} catch (URISyntaxException e) {
return null;
}
}
public ResourceLoader createSubloader(final String relativePath, final String rootName) {
final String ourRelativePath = this.relativePath;
final String fixedPath = PathUtils.relativize(PathUtils.canonicalize(relativePath));
return new JarFileResourceLoader(rootName, jarFile, ourRelativePath == null ? fixedPath : ourRelativePath + "/" + fixedPath);
}
static void extractJarPaths(final JarFile jarFile, String relativePath,
final Collection index) {
index.add("");
final Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry jarEntry = entries.nextElement();
final String name = jarEntry.getName();
final int idx = name.lastIndexOf('/');
if (idx == -1) continue;
final String path = name.substring(0, idx);
if (path.length() == 0 || path.endsWith("/")) {
// invalid name, just skip...
continue;
}
if (relativePath == null) {
index.add(path);
} else {
if (path.startsWith(relativePath + "/")) {
index.add(path.substring(relativePath.length() + 1));
}
}
}
}
static void writeExternalIndex(final File indexFile,
final Collection index) {
// Now try to write it
boolean ok = false;
try {
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexFile)))) {
for (String name : index) {
writer.write(name);
writer.write('\n');
}
writer.close();
ok = true;
}
} catch (IOException e) {
// failed, ignore
} finally {
if (! ok) {
// well, we tried...
indexFile.delete();
}
}
}
static Collection readIndex(final InputStream stream, final Collection index, final String relativePath) throws IOException {
final BufferedReader r = new BufferedReader(new InputStreamReader(stream));
try {
String s;
while ((s = r.readLine()) != null) {
String name = s.trim();
if (relativePath == null) {
index.add(name);
} else {
if (name.startsWith(relativePath + "/")) {
index.add(name.substring(relativePath.length() + 1));
}
}
}
return index;
} finally {
// if exception is thrown, undo index creation
r.close();
}
}
static void addInternalIndex(File file, boolean modify) throws IOException {
try (final JarFile oldJarFile = JDKSpecific.getJarFile(file, false)) {
final Collection index = new TreeSet();
final File outputFile;
outputFile = new File(file.getAbsolutePath().replace(".jar", "-indexed.jar"));
try (final ZipOutputStream zo = new ZipOutputStream(new FileOutputStream(outputFile))) {
Enumeration entries = oldJarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
// copy data, unless we're replacing the index
if (!entry.getName().equals(INDEX_FILE)) {
final JarEntry clone = (JarEntry) entry.clone();
// Compression level and format can vary across implementations
if (clone.getMethod() != ZipEntry.STORED)
clone.setCompressedSize(-1);
zo.putNextEntry(clone);
Utils.copy(oldJarFile.getInputStream(entry), zo);
}
// add to the index
final String name = entry.getName();
final int idx = name.lastIndexOf('/');
if (idx == -1) continue;
final String path = name.substring(0, idx);
if (path.length() == 0 || path.endsWith("/")) {
// invalid name, just skip...
continue;
}
index.add(path);
}
// write index
zo.putNextEntry(new ZipEntry(INDEX_FILE));
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zo))) {
for (final String name : index) {
writer.write(name);
writer.write('\n');
}
}
zo.close();
oldJarFile.close();
if (modify) {
file.delete();
if (!outputFile.renameTo(file)) {
throw new IOException("failed to rename " + outputFile.getAbsolutePath() + " to " + file.getAbsolutePath());
}
}
}
}
}
private static final CodeSigners EMPTY_CODE_SIGNERS = new CodeSigners(new CodeSigner[0]);
static final class CodeSigners {
private final CodeSigner[] codeSigners;
private final int hashCode;
CodeSigners(final CodeSigner[] codeSigners) {
this.codeSigners = codeSigners;
hashCode = Arrays.hashCode(codeSigners);
}
public boolean equals(final Object obj) {
return obj instanceof CodeSigners && equals((CodeSigners) obj);
}
private boolean equals(final CodeSigners other) {
return Arrays.equals(codeSigners, other.codeSigners);
}
public int hashCode() {
return hashCode;
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/JarModuleFinder.java 0000775 0000000 0000000 00000020172 13417133242 0027234 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.jboss.modules.filter.MultiplePathFilterBuilder;
import org.jboss.modules.filter.PathFilters;
import org.jboss.modules.xml.ModuleXmlParser;
import static org.jboss.modules.Utils.DEPENDENCIES;
import static org.jboss.modules.Utils.EXPORT;
import static org.jboss.modules.Utils.OPTIONAL;
import static org.jboss.modules.Utils.MODULES_DIR;
import static org.jboss.modules.Utils.MODULE_FILE;
/**
* A module finder which uses a JAR file as a module repository.
*
* @author David M. Lloyd
* @author Richard Opalka
* @deprecated {@link FileSystemClassPathModuleFinder} and/or {@link ResourceLoaderModuleFinder} should be used instead for more
* complete functionality.
*/
@Deprecated
public final class JarModuleFinder implements ModuleFinder {
private final String myName;
private final JarFile jarFile;
private final AccessControlContext context;
/**
* Construct a new instance.
*
* @param myIdentifier the identifier to use for the JAR itself
* @param jarFile the JAR file to encapsulate
*/
public JarModuleFinder(final ModuleIdentifier myIdentifier, final JarFile jarFile) {
this(myIdentifier.toString(), jarFile);
}
/**
* Construct a new instance.
*
* @param myName the name to use for the JAR itself
* @param jarFile the JAR file to encapsulate
*/
public JarModuleFinder(final String myName, final JarFile jarFile) {
this.myName = myName;
this.jarFile = jarFile;
context = AccessController.getContext();
}
public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) throws ModuleLoadException {
if (name.equals(myName)) {
// special root JAR module
Manifest manifest;
try {
manifest = jarFile.getManifest();
} catch (IOException e) {
throw new ModuleLoadException("Failed to load MANIFEST from JAR", e);
}
ModuleSpec.Builder builder = ModuleSpec.build(name);
Attributes mainAttributes = manifest.getMainAttributes();
String mainClass = mainAttributes.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
builder.setMainClass(mainClass);
}
String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
String dependencies = mainAttributes.getValue(DEPENDENCIES);
MultiplePathFilterBuilder pathFilterBuilder = PathFilters.multiplePathFilterBuilder(true);
pathFilterBuilder.addFilter(PathFilters.is(MODULES_DIR), false);
pathFilterBuilder.addFilter(PathFilters.isChildOf(MODULES_DIR), false);
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader("", jarFile), pathFilterBuilder.create()));
String[] classPathEntries = classPath == null ? Utils.NO_STRINGS : classPath.split("\\s+");
for (String entry : classPathEntries) {
if (! entry.isEmpty()) {
if (entry.startsWith("../") || entry.startsWith("./") || entry.startsWith("/") || entry.contains("/../")) {
// invalid
continue;
}
File root;
try {
File path = new File(new URI(entry));
if (path.isAbsolute()) {
root = path;
} else {
root = new File(jarFile.getName(), path.getPath());
}
} catch (URISyntaxException e) {
// invalid, will probably fail anyway
root = new File(jarFile.getName(), entry);
}
if (entry.endsWith("/")) {
// directory reference
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new PathResourceLoader(entry, root.toPath(), context)));
} else {
// assume a JAR
JarFile childJarFile;
try {
childJarFile = JDKSpecific.getJarFile(root, true);
} catch (IOException e) {
// ignore and continue
continue;
}
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader(entry, childJarFile)));
}
}
}
String[] dependencyEntries = dependencies == null ? Utils.NO_STRINGS : dependencies.split("\\s*,\\s*");
for (String dependencyEntry : dependencyEntries) {
boolean optional = false;
boolean export = false;
dependencyEntry = dependencyEntry.trim();
if (! dependencyEntry.isEmpty()) {
String[] fields = dependencyEntry.split("\\s+");
if (fields.length < 1) {
continue;
}
String moduleName = fields[0];
for (int i = 1; i < fields.length; i++) {
String field = fields[i];
if (field.equals(OPTIONAL)) {
optional = true;
} else if (field.equals(EXPORT)) {
export = true;
}
// else ignored
}
builder.addDependency(new ModuleDependencySpecBuilder()
.setName(moduleName)
.setExport(export)
.setOptional(optional)
.build());
}
}
builder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK));
builder.addDependency(DependencySpec.createLocalDependencySpec());
return builder.create();
} else {
final String path = PathUtils.basicModuleNameToPath(name);
if (path == null) {
return null; // not valid, so not found
}
String basePath = MODULES_DIR + "/" + path;
JarEntry moduleXmlEntry = jarFile.getJarEntry(basePath + "/" + MODULE_FILE);
if (moduleXmlEntry == null) {
return null;
}
ModuleSpec moduleSpec;
try {
try (final InputStream inputStream = jarFile.getInputStream(moduleXmlEntry)) {
moduleSpec = ModuleXmlParser.parseModuleXml((rootPath, loaderPath, loaderName) -> new JarFileResourceLoader(loaderName, jarFile, loaderPath), basePath, inputStream, moduleXmlEntry.getName(), delegateLoader, name);
}
} catch (IOException e) {
throw new ModuleLoadException("Failed to read " + MODULE_FILE + " file", e);
}
return moduleSpec;
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LayeredModulePathFactory.java 0000664 0000000 0000000 00000022003 13417133242 0031112 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
/**
* Provides a module path that includes entries for any "layer" and "add-on" directory structures found
* within the regular items in the provided module path.
*
* @author Brian Stansberry (c) 2012 Red Hat Inc.
*/
class LayeredModulePathFactory {
/**
* Inspects each element in the given {@code modulePath} to see if it includes a {@code layers.conf} file
* and/or a standard directory structure with child directories {@code system/layers} and, optionally,
* {@code system/add-ons}. If so, the layers identified in {@code layers.conf} are added to the module path
*
* @param modulePath the filesystem locations that make up the standard module path, each of which is to be
* checked for the presence of layers and add-ons
*
* @return a new module path, including any layers and add-ons, if found
*/
static File[] resolveLayeredModulePath(File... modulePath) {
boolean foundLayers = false;
List layeredPath = new ArrayList();
for (File file : modulePath) {
// Always add the root, as the user may place modules directly in it
layeredPath.add(file);
LayersConfig layersConfig = getLayersConfig(file);
File layersDir = new File(file, layersConfig.getLayersPath());
if (!layersDir.exists()) {
if (layersConfig.isConfigured()) {
// Bad config from user
throw new IllegalStateException("No layers directory found at " + layersDir);
}
// else this isn't a root that has layers and add-ons
continue;
}
boolean validLayers = true;
List layerFiles = new ArrayList();
for (String layerName : layersConfig.getLayers()) {
File layer = new File(layersDir, layerName);
if (!layer.exists()) {
if (layersConfig.isConfigured()) {
// Bad config from user
throw new IllegalStateException(String.format("Cannot find layer %s under directory %s", layerName, layersDir));
}
// else this isn't a standard layers and add-ons structure
validLayers = false;
break;
}
loadOverlays(layer, layerFiles);
}
if (validLayers) {
foundLayers = true;
layeredPath.addAll(layerFiles);
// Now add-ons
File[] addOns = new File(file, layersConfig.getAddOnsPath()).listFiles();
if (addOns != null) {
for (File addOn : addOns) {
if (addOn.isDirectory()) {
loadOverlays(addOn, layeredPath);
}
}
}
}
}
return foundLayers ? layeredPath.toArray(new File[layeredPath.size()]) : modulePath;
}
private static LayersConfig getLayersConfig(File repoRoot) {
File layersList = new File(repoRoot, "layers.conf");
if (!layersList.exists()) {
return new LayersConfig();
}
try (final Reader reader = new InputStreamReader(new FileInputStream(layersList), "UTF-8")) {
Properties props = new Properties();
props.load(reader);
return new LayersConfig(props);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static class LayersConfig {
private static final String DEFAULT_LAYERS_PATH = "system/layers";
private static final String DEFAULT_ADD_ONS_PATH = "system/add-ons";
private final boolean configured;
private final String layersPath;
private final String addOnsPath;
private final List layers;
private LayersConfig() {
configured = false;
layersPath = DEFAULT_LAYERS_PATH;
addOnsPath = DEFAULT_ADD_ONS_PATH;
layers = Collections.singletonList("base");
}
private LayersConfig(Properties properties) {
configured = true;
// Possible future enhancement; probably better to use an xml file
// layersPath = properties.getProperty("layers.path", DEFAULT_LAYERS_PATH);
// addOnsPath = properties.getProperty("add-ons.path", DEFAULT_ADD_ONS_PATH);
// boolean excludeBase = Boolean.valueOf(properties.getProperty("exclude.base.layer", "false"));
layersPath = DEFAULT_LAYERS_PATH;
addOnsPath = DEFAULT_ADD_ONS_PATH;
boolean excludeBase = false;
String layersProp = (String) properties.get("layers");
if (layersProp == null || (layersProp = layersProp.trim()).length() == 0) {
if (excludeBase) {
layers = Collections.emptyList();
} else {
layers = Collections.singletonList("base");
}
} else {
String[] layerNames = layersProp.split(",");
layers = new ArrayList();
boolean hasBase = false;
for (String layerName : layerNames) {
if ("base".equals(layerName)) {
hasBase = true;
}
layers.add(layerName);
}
if (!hasBase && !excludeBase) {
layers.add("base");
}
}
}
boolean isConfigured() {
return configured;
}
String getLayersPath() {
return layersPath;
}
String getAddOnsPath() {
return addOnsPath;
}
List getLayers() {
return layers;
}
}
private static final String OVERLAYS = ".overlays";
/**
* Load the overlays for each layer.
*
* @param layeringRoot the layer root
* @param path the module path
*/
static void loadOverlays(final File layeringRoot, final List path) {
final File overlays = new File(layeringRoot, OVERLAYS);
if (overlays.exists()) {
final File refs = new File(overlays, OVERLAYS);
if (refs.exists()) {
try {
for (final String overlay : readRefs(refs)) {
final File root = new File(overlays, overlay);
path.add(root);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
path.add(layeringRoot);
}
public static List readRefs(final File file) throws IOException {
if(! file.exists()) {
return Collections.emptyList();
}
final InputStream is = new FileInputStream(file);
try {
return readRefs(is);
} finally {
if (is != null) try {
is.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
static List readRefs(final InputStream is) throws IOException {
final List refs = new ArrayList();
final StringBuffer buffer = new StringBuffer();
do {
if(buffer.length() > 0) {
final String ref = buffer.toString().trim();
if(ref.length() > 0) {
refs.add(ref);
}
}
} while(readLine(is, buffer));
return refs;
}
static boolean readLine(InputStream is, StringBuffer buffer) throws IOException {
buffer.setLength(0);
int c;
for(;;) {
c = is.read();
switch(c) {
case '\t':
case '\r':
break;
case -1: return false;
case '\n': return true;
default: buffer.append((char) c);
}
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/Linkage.java 0000664 0000000 0000000 00000004624 13417133242 0025575 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* The linkage state of a module.
*
* @author David M. Lloyd
*/
final class Linkage {
private static final Dependency[] NO_DEPENDENCIES = new Dependency[0];
private static final DependencySpec[] NO_DEPENDENCY_SPECS = new DependencySpec[0];
enum State {
NEW,
UNLINKED,
LINKING,
LINKED,
;
}
private final DependencySpec[] dependencySpecs;
private final Dependency[] dependencies;
private final State state;
private final Map> allPaths;
Linkage(final State state) {
this(NO_DEPENDENCY_SPECS, NO_DEPENDENCIES, state, Collections.>emptyMap());
}
Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state) {
this(dependencySpecs, dependencies, state, Collections.>emptyMap());
}
Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state, final Map> allPaths) {
this.dependencySpecs = dependencySpecs;
this.dependencies = dependencies;
this.state = state;
this.allPaths = PathUtils.deduplicateLists(allPaths);
}
Map> getPaths() {
return allPaths;
}
State getState() {
return state;
}
Dependency[] getDependencies() {
return dependencies;
}
DependencySpec[] getDependencySpecs() {
return dependencySpecs;
}
static final Linkage NONE = new Linkage(State.NEW);
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalDependency.java 0000664 0000000 0000000 00000003340 13417133242 0027246 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
/**
* @author David M. Lloyd
*/
final class LocalDependency extends Dependency {
private final LocalLoader localLoader;
private final Set paths;
LocalDependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter, final LocalLoader localLoader, final Set paths) {
super(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter);
this.localLoader = localLoader;
this.paths = paths;
}
LocalLoader getLocalLoader() {
return localLoader;
}
Set getPaths() {
return paths;
}
public String toString() {
return "dependency on " + localLoader;
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalDependencySpec.java 0000664 0000000 0000000 00000003513 13417133242 0030063 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2018 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
final class LocalDependencySpec extends DependencySpec {
private final LocalLoader localLoader;
private final Set loaderPaths;
LocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final LocalLoader localLoader, final Set loaderPaths) {
super(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter);
this.localLoader = localLoader;
this.loaderPaths = loaderPaths;
}
Dependency getDependency(final Module module) {
return new LocalDependency(getExportFilter(), getImportFilter(), getResourceExportFilter(), getResourceImportFilter(), getClassExportFilter(), getClassImportFilter(), localLoader, loaderPaths);
}
public String toString() {
return "dependency on local loader " + localLoader;
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalDependencySpecBuilder.java 0000664 0000000 0000000 00000012011 13417133242 0031363 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A local dependency specification builder, which includes a module's own content or some other, external content.
*/
public final class LocalDependencySpecBuilder extends DependencySpecBuilder {
private LocalLoader localLoader;
private Set loaderPaths = Collections.emptySet();
/**
* Construct a new instance.
*/
public LocalDependencySpecBuilder() {
// different default import filter
setImportFilter(PathFilters.acceptAll());
}
// covariant overrides
/**
* Get the import filter to use. The default value is {@link PathFilters#acceptAll()}.
*
* @return the import filter to use
*/
public PathFilter getImportFilter() {
return super.getImportFilter();
}
public LocalDependencySpecBuilder setImportFilter(final PathFilter importFilter) {
super.setImportFilter(importFilter);
return this;
}
public LocalDependencySpecBuilder setImportServices(final boolean services) {
super.setImportServices(services);
return this;
}
public LocalDependencySpecBuilder setExportFilter(final PathFilter exportFilter) {
super.setExportFilter(exportFilter);
return this;
}
public LocalDependencySpecBuilder setExport(final boolean export) {
super.setExport(export);
return this;
}
public LocalDependencySpecBuilder setResourceImportFilter(final PathFilter resourceImportFilter) {
super.setResourceImportFilter(resourceImportFilter);
return this;
}
public LocalDependencySpecBuilder setResourceExportFilter(final PathFilter resourceExportFilter) {
super.setResourceExportFilter(resourceExportFilter);
return this;
}
public LocalDependencySpecBuilder setClassImportFilter(final ClassFilter classImportFilter) {
super.setClassImportFilter(classImportFilter);
return this;
}
public LocalDependencySpecBuilder setClassExportFilter(final ClassFilter classExportFilter) {
super.setClassExportFilter(classExportFilter);
return this;
}
/**
* Get the local loader to use. The default value is {@code null}, indicating that the content should come from
* the module being defined.
*
* @return the local loader to use, or {@code null} to use the module's own content
*/
public LocalLoader getLocalLoader() {
return localLoader;
}
/**
* Set the local loader to use.
*
* @param localLoader the local loader to use, or {@code null} to use the module's own content
* @return this builder
*/
public LocalDependencySpecBuilder setLocalLoader(final LocalLoader localLoader) {
if (localLoader == null) {
throw new IllegalArgumentException("localLoader is null");
}
this.localLoader = localLoader;
return this;
}
/**
* Get the loader paths set. The default is the empty set. This value is ignored if the dependency specification
* refers to the module's own content.
*
* @return the loader paths set
*/
public Set getLoaderPaths() {
return loaderPaths;
}
/**
* Set the loader paths set.
*
* @param loaderPaths the loader paths set (must not be {@code null})
* @return this builder
*/
public LocalDependencySpecBuilder setLoaderPaths(final Set loaderPaths) {
if (loaderPaths == null) {
throw new IllegalArgumentException("loaderPaths is null");
}
this.loaderPaths = loaderPaths;
return this;
}
public DependencySpec build() {
final LocalLoader localLoader = this.localLoader;
final Set loaderPaths = this.loaderPaths;
if (localLoader == null) {
return new ModuleClassLoaderDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter);
} else {
return new LocalDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter, localLoader, loaderPaths);
}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalLoader.java 0000664 0000000 0000000 00000004112 13417133242 0026374 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.util.List;
/**
* A loader which implements the local part of a module.
*
* Thread safety warning! The loader must never call into a class loader (or any other object) which may
* take locks and subsequently delegate to a module class loader. This will cause deadlocks and other hard-to-debug
* concurrency problems.
*
* @author David M. Lloyd
*/
public interface LocalLoader {
/**
* Load a class which is locally defined by this loader.
*
* @param name the class name
* @param resolve {@code true} to resolve the class
* @return the class, or {@code null} if there is no local class with this name
*/
Class> loadClassLocal(String name, boolean resolve);
/**
* Load a package which is locally defined by this loader.
*
* @param name the package name
* @return the package, or {@code null} if there is no local package with this name
*/
Package loadPackageLocal(String name);
/**
* Load a resource which is locally defined by this loader. The given name is a path separated
* by "{@code /}" characters.
*
* @param name the resource path
* @return the resource or resources, or an empty list if there is no local resource with this name
*/
List loadResourceLocal(String name);
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalLoaders.java 0000664 0000000 0000000 00000007744 13417133242 0026575 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* Static factory methods for various types of local loaders.
*
* @apiviz.exclude
*
* @author David M. Lloyd
*/
public final class LocalLoaders {
private LocalLoaders() {
}
/**
* Create a filtered local loader.
*
* @param pathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createPathFilteredLocalLoader(final PathFilter pathFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param pathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterablePathFilteredLocalLoader(final PathFilter pathFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createClassFilteredLocalLoader(final ClassFilter classFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterableClassFilteredLocalLoader(final ClassFilter classFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param resourcePathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(classFilter, resourcePathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param resourcePathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterableFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(classFilter, resourcePathFilter, originalLoader);
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalModuleFinder.java 0000664 0000000 0000000 00000036112 13417133242 0027550 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.Predicate;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
import org.jboss.modules.xml.ModuleXmlParser;
import static java.security.AccessController.doPrivileged;
import static org.jboss.modules.Utils.MODULE_FILE;
/**
* A module finder which locates module specifications which are stored in a local module
* repository on the filesystem, which uses {@code module.xml} descriptors.
*
* @author David M. Lloyd
* @author Richard Opalka
*/
public final class LocalModuleFinder implements IterableModuleFinder, AutoCloseable {
private static final File[] NO_FILES = new File[0];
private final File[] repoRoots;
private final PathFilter pathFilter;
private final AccessControlContext accessControlContext;
private final List resourceLoaderList = new ArrayList<>(64);
private final ModuleXmlParser.ResourceRootFactory resourceRootFactory;
private static final ResourceLoader TERMINATED_MARKER = new ResourceLoader() {
public String getRootName() {
return null;
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
return null;
}
public PackageSpec getPackageSpec(final String name) throws IOException {
return null;
}
public Resource getResource(final String name) {
return null;
}
public String getLibrary(final String name) {
return null;
}
public Collection getPaths() {
return null;
}
};
private LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter, final boolean cloneRoots) {
this.repoRoots = cloneRoots && repoRoots.length > 0 ? repoRoots.clone() : repoRoots;
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
for (File repoRoot : this.repoRoots) {
if (repoRoot != null) sm.checkPermission(new FilePermission(new File(repoRoot, "-").getPath(), "read"));
}
}
this.pathFilter = pathFilter;
this.accessControlContext = AccessController.getContext();
resourceRootFactory = (rootPath, loaderPath, loaderName) -> {
final ResourceLoader loader = ModuleXmlParser.ResourceRootFactory.getDefault().createResourceLoader(rootPath, loaderPath, loaderName);
final List list = this.resourceLoaderList;
synchronized (list) {
if (list.size() == 1 && list.get(0) == TERMINATED_MARKER) {
safeClose(loader);
throw new IllegalStateException("Module finder is closed");
}
list.add(loader);
}
return loader;
};
}
/**
* Construct a new instance.
*
* @param repoRoots the repository roots to use
* @param pathFilter the path filter to use
*/
public LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter) {
this(repoRoots, pathFilter, true);
}
/**
* Construct a new instance.
*
* @param repoRoots the repository roots to use
*/
public LocalModuleFinder(final File[] repoRoots) {
this(repoRoots, PathFilters.acceptAll());
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*
* This is equivalent to a call to {@link LocalModuleFinder#LocalModuleFinder(boolean) LocalModuleFinder(true)}.
*
*/
public LocalModuleFinder() {
this(true);
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*
* @param supportLayersAndAddOns {@code true} if the identified module repository roots should be checked for
* an internal structure of child "layer" and "add-on" directories that may also
* be treated as module roots lower in precedence than the parent root. Any "layers"
* subdirectories whose names are specified in a {@code layers.conf} file found in
* the module repository root will be added in the precedence of order specified
* in the {@code layers.conf} file; all "add-on" subdirectories will be added at
* a lower precedence than all "layers" and with no guaranteed precedence order
* between them. If {@code false} no check for "layer" and "add-on" directories
* will be performed.
*
*/
public LocalModuleFinder(boolean supportLayersAndAddOns) {
this(getRepoRoots(supportLayersAndAddOns), PathFilters.acceptAll(), false);
}
static File[] getRepoRoots(final boolean supportLayersAndAddOns) {
return supportLayersAndAddOns ? LayeredModulePathFactory.resolveLayeredModulePath(getModulePathFiles()) : getModulePathFiles();
}
private static File[] getModulePathFiles() {
return getFiles(System.getProperty("module.path", System.getenv("JAVA_MODULEPATH")), 0, 0);
}
private static File[] getFiles(final String modulePath, final int stringIdx, final int arrayIdx) {
if (modulePath == null) return NO_FILES;
final int i = modulePath.indexOf(File.pathSeparatorChar, stringIdx);
final File[] files;
if (i == -1) {
files = new File[arrayIdx + 1];
files[arrayIdx] = new File(modulePath.substring(stringIdx)).getAbsoluteFile();
} else {
files = getFiles(modulePath, i + 1, arrayIdx + 1);
files[arrayIdx] = new File(modulePath.substring(stringIdx, i)).getAbsoluteFile();
}
return files;
}
public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) throws ModuleLoadException {
final String child = PathUtils.basicModuleNameToPath(name);
if (child == null) {
return null; // not valid, so not found
}
final PathFilter pathFilter = this.pathFilter;
if (pathFilter.accept(child + "/")) {
try {
return doPrivileged((PrivilegedExceptionAction) () -> parseModuleXmlFile(resourceRootFactory, name, delegateLoader, repoRoots), accessControlContext);
} catch (PrivilegedActionException e) {
try {
throw e.getCause();
} catch (IOException e1) {
throw new ModuleLoadException(e1);
} catch (RuntimeException | Error | ModuleLoadException e1) {
throw e1;
} catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
}
return null;
}
/**
* Parse a {@code module.xml} file and return the corresponding module specification.
*
* @param identifier the identifier to load
* @param delegateLoader the delegate module loader to use for module specifications
* @param roots the repository root paths to search
* @return the module specification
* @throws IOException if reading the module file failed
* @throws ModuleLoadException if creating the module specification failed (e.g. due to a parse error)
* @deprecated Use {@link #parseModuleXmlFile(String, ModuleLoader, File...)} instead.
*/
@Deprecated
public static ModuleSpec parseModuleXmlFile(final ModuleIdentifier identifier, final ModuleLoader delegateLoader, final File... roots) throws IOException, ModuleLoadException {
return parseModuleXmlFile(identifier.toString(), delegateLoader, roots);
}
/**
* Parse a {@code module.xml} file and return the corresponding module specification.
*
* @param name the name of the module to load
* @param delegateLoader the delegate module loader to use for module specifications
* @param roots the repository root paths to search
* @return the module specification
* @throws IOException if reading the module file failed
* @throws ModuleLoadException if creating the module specification failed (e.g. due to a parse error)
*/
public static ModuleSpec parseModuleXmlFile(final String name, final ModuleLoader delegateLoader, final File... roots) throws IOException, ModuleLoadException {
return parseModuleXmlFile(ModuleXmlParser.ResourceRootFactory.getDefault(), name, delegateLoader, roots);
}
static ModuleSpec parseModuleXmlFile(final ModuleXmlParser.ResourceRootFactory factory, final String name, final ModuleLoader delegateLoader, final File... roots) throws IOException, ModuleLoadException {
final String child = PathUtils.basicModuleNameToPath(name);
if (child == null) {
return null; // not valid, so not found
}
for (File root : roots) {
File file = new File(root, child);
File moduleXml = new File(file, MODULE_FILE);
if (moduleXml.exists()) {
final ModuleSpec spec = ModuleXmlParser.parseModuleXml(factory, delegateLoader, name, file, moduleXml);
if (spec == null) break;
return spec;
}
}
return null;
}
private static final Path MODULE_FILE_PATH = new File(MODULE_FILE).toPath();
private static final Predicate ITER_FILTER = new Predicate() {
public boolean test(final Path path) {
final Path fileName = path.getFileName();
return fileName != null && fileName.equals(MODULE_FILE_PATH);
}
};
public Iterator iterateModules(final String baseName, final boolean recursive) {
return new Iterator() {
private final Iterator rootIter = Arrays.asList(repoRoots).iterator();
private final Set found = new HashSet<>();
private Path rootPath;
private Iterator pathIter;
private String next;
public boolean hasNext() {
while (next == null) {
while (pathIter == null) {
if (! rootIter.hasNext()) {
return false;
}
Path path = rootIter.next().toPath();
rootPath = path;
if (baseName != null && ! baseName.isEmpty()) {
path = path.resolve(PathUtils.basicModuleNameToPath(baseName));
}
try {
pathIter = Files.walk(path, recursive ? Integer.MAX_VALUE : 1).filter(ITER_FILTER).iterator();
} catch (IOException ignored) {
pathIter = null;
continue;
}
}
if (pathIter.hasNext()) {
final Path nextPath = pathIter.next();
if (nextPath.getParent() == null) {
continue;
}
try (InputStream stream = Files.newInputStream(nextPath)) {
final ModuleSpec moduleSpec = ModuleXmlParser.parseModuleXml(ModuleXmlParser.ResourceRootFactory.getDefault(), nextPath.getParent().toString(), stream, nextPath.toString(), null, (String)null);
this.next = moduleSpec.getName();
if (found.add(this.next)) {
return true;
}
this.next = null;
} catch (IOException | ModuleLoadException e) {
// ignore
}
} else {
pathIter = null;
}
}
return true;
}
public String next() {
if (! hasNext()) throw new NoSuchElementException();
try {
return next;
} finally {
next = null;
}
}
};
}
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("local module finder @").append(Integer.toHexString(hashCode())).append(" (roots: ");
final int repoRootsLength = repoRoots.length;
for (int i = 0; i < repoRootsLength; i++) {
final File root = repoRoots[i];
b.append(root);
if (i != repoRootsLength - 1) {
b.append(',');
}
}
b.append(')');
return b.toString();
}
/**
* Close this module loader and release all backing files. Note that subsequent load attempts will fail with an
* error after this method is called.
*/
public void close() {
final List list = this.resourceLoaderList;
final ArrayList toClose;
synchronized (list) {
if (list.size() == 1 && list.get(0) == TERMINATED_MARKER) {
return;
}
toClose = new ArrayList<>(list);
list.clear();
list.add(TERMINATED_MARKER);
}
for (ResourceLoader resourceLoader : toClose) {
safeClose(resourceLoader);
}
}
private static void safeClose(AutoCloseable closeable) {
if (closeable != null) try {
closeable.close();
} catch (Throwable ignored) {}
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/LocalModuleLoader.java 0000664 0000000 0000000 00000005261 13417133242 0027550 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import java.io.File;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A local filesystem-backed module loader.
*
* @author John Bailey
* @author David M. Lloyd
*/
public final class LocalModuleLoader extends DelegatingModuleLoader implements AutoCloseable {
/**
* Construct a new instance.
*
* @param repoRoots the array of repository roots to look for modules
*/
public LocalModuleLoader(final File[] repoRoots) {
this(repoRoots, PathFilters.acceptAll());
}
/**
* Construct a new instance.
*
* @param repoRoots the array of repository roots to look for modules
* @param pathFilter the path filter to apply to roots
*/
public LocalModuleLoader(final File[] repoRoots, final PathFilter pathFilter) {
super(Utils.JDK_MODULE_LOADER, new ModuleFinder[] { new LocalModuleFinder(repoRoots, pathFilter)});
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*/
public LocalModuleLoader() {
super(Utils.JDK_MODULE_LOADER, new ModuleFinder[] { new LocalModuleFinder() });
}
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("local module loader @").append(Integer.toHexString(hashCode())).append(" (finder: ").append(getFinders()[0]).append(')');
return b.toString();
}
/**
* Close this module loader and release all backing files. Note that subsequent load attempts will fail with an
* error after this method is called.
*/
public void close() {
final ModuleFinder[] finders = getFinders();
assert finders.length == 1 && finders[0] instanceof LocalModuleFinder;
((LocalModuleFinder)finders[0]).close();
}
}
jboss-modules-1.9.0.Final/src/main/java/org/jboss/modules/Main.java 0000664 0000000 0000000 00000073732 13417133242 0025115 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.modules;
import __redirected.__JAXPRedirected;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Policy;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.logging.LogManager;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jboss.modules.log.JDKModuleLogger;
import org.jboss.modules.log.StreamModuleLogger;
import static java.security.AccessController.doPrivileged;
import static org.jboss.modules.SecurityActions.setContextClassLoader;
/**
* The main entry point of JBoss Modules when run as a JAR on the command line.
*
* @author David M. Lloyd
* @author Jason T. Greene
* @apiviz.exclude
*/
public final class Main {
static {
// Force initialization at the earliest possible point
@SuppressWarnings("unused")
long start = StartTimeHolder.START_TIME;
}
private static final String[] NO_STRINGS = new String[0];
private Main() {
}
private static void usage() {
System.out.println("Usage: java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -jar [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -cp [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -class [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar -addindex [-modify] ");
System.out.println("where is a valid module specification string");
System.out.println("and options include:");
System.out.println(" -help Display this message");
System.out.println(" -mp, -modulepath ");
System.out.println(" A list of directories, separated by '" + File.pathSeparator + "', where modules may be located");
System.out.println(" If not specified, the value of the \"module.path\" system property is used");
System.out.println(" -class Specify that the final argument is a");
System.out.println(" class to load from the class path; not compatible with -jar");
System.out.println(" -cp,-classpath ");
System.out.println(" A search path for class files; implies -class");
System.out.println(" -dep,-dependencies [,,...]");
System.out.println(" A list of module dependencies to add to the class path;");
System.out.println(" requires -class or -cp");
System.out.println(" -deptree Print the dependency tree of the given module instead of running it");
System.out.println(" -debuglog Enable debug mode output to System.out during bootstrap before any logging manager is installed");
System.out.println(" -jar Specify that the final argument is the name of a");
System.out.println(" JAR file to run as a module; not compatible with -class");
System.out.println(" -jaxpmodule ");
System.out.println(" The default JAXP implementation to use of the JDK");
System.out.println(" -secmgr Run with a security manager installed; not compatible with -secmgrmodule");
System.out.println(" -secmgrmodule ");
System.out.println(" Run with a security manager module; not compatible with -secmgr");
System.out.println(" -add-provider [/]");
System.out.println(" Add a security provider of the given module and class (can be given more than once)");
System.out.println(" -addindex Specify that the final argument is a");
System.out.println(" jar to create an index for");
System.out.println(" -modify Modify the indexes jar in-place");
System.out.println(" -version Print version and exit\n");
}
/**
* Run JBoss Modules.
*
* @param args the command-line arguments
*
* @throws Throwable if an error occurs
*/
public static void main(String[] args) throws Throwable {
final int argsLen = args.length;
String deps = null;
String[] moduleArgs = NO_STRINGS;
String modulePath = null;
String classpath = null;
boolean jar = false;
boolean classpathDefined = false;
boolean classDefined = false;
boolean depTree = false;
String nameArgument = null;
String jaxpModuleName = null;
boolean defaultSecMgr = false;
String secMgrModule = null;
boolean addIndex = false;
boolean modifyInPlace = false;
boolean debuglog = false;
final List addedProviders = new ArrayList<>();
for (int i = 0; i < argsLen; i++) {
final String arg = args[i];
try {
if (arg.charAt(0) == '-') {
// it's an option
if ("-version".equals(arg)) {
System.out.println("JBoss Modules version " + getVersionString());
return;
} else if ("-help".equals(arg)) {
usage();
return;
} else if ("-addindex".equals(arg)) {
addIndex = true;
} else if ("-modify".equals(arg)) {
modifyInPlace = true;
} else if ("-modulepath".equals(arg) || "-mp".equals(arg)) {
if (modulePath != null) {
System.err.println("Module path may only be specified once");
System.exit(1);
}
modulePath = args[++i];
System.setProperty("module.path", modulePath);
} else if ("-config".equals(arg)) {
System.err.println("Config files are no longer supported. Use the -mp option instead");
System.exit(1);
} else if ("-deptree".equals(arg)) {
if (depTree) {
System.err.println("-deptree may only be specified once");
System.exit(1);
}
if (jar) {
System.err.println("-deptree may not be specified with -jar");
System.exit(1);
}
if (classDefined) {
System.err.println("-deptree may not be specified with -class");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-deptree may not be specified with -classpath");
System.exit(1);
}
depTree = true;
} else if ("-debuglog".equals(arg)) {
debuglog = true;
} else if ("-jaxpmodule".equals(arg)) {
jaxpModuleName = args[++i];
} else if ("-jar".equals(arg)) {
if (jar) {
System.err.println("-jar flag may only be specified once");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-cp/-classpath may not be specified with -jar");
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -jar");
System.exit(1);
}
jar = true;
} else if ("-cp".equals(arg) || "-classpath".equals(arg)) {
if (classpathDefined) {
System.err.println("-cp or -classpath may only be specified once.");
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be specified with -cp/classpath");
System.exit(1);
}
if (jar) {
System.err.println("-cp/-classpath may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -classpath");
System.exit(1);
}
classpathDefined = true;
classpath = args[++i];
doPrivileged(new PropertyWriteAction("java.class.path", classpath));
} else if ("-dep".equals(arg) || "-dependencies".equals(arg)) {
if (deps != null) {
System.err.println("-dep or -dependencies may only be specified once.");
System.exit(1);
}
deps = args[++i];
} else if ("-class".equals(arg)) {
if (classDefined) {
System.err.println("-class flag may only be specified once");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-class may not be specified with -cp/classpath");
System.exit(1);
}
if (jar) {
System.err.println("-class may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -class");
System.exit(1);
}
classDefined = true;
} else if ("-logmodule".equals(arg)) {
System.err.println("WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager' or the 'java.util.logging.LogManager' service loader.");
i++;
} else if ("-secmgr".equals(arg)) {
if (defaultSecMgr) {
System.err.println("-secmgr may only be specified once");
System.exit(1);
}
if (secMgrModule != null) {
System.err.println("-secmgr may not be specified when -secmgrmodule is given");
System.exit(1);
}
defaultSecMgr = true;
} else if ("-secmgrmodule".equals(arg)) {
if (secMgrModule != null) {
System.err.println("-secmgrmodule may only be specified once");
System.exit(1);
}
if (defaultSecMgr) {
System.err.println("-secmgrmodule may not be specified when -secmgr is given");
System.exit(1);
}
secMgrModule = args[++ i];
} else if ("-add-provider".equals(arg)) {
addedProviders.add(args[++ i]);
} else {
System.err.printf("Invalid option '%s'\n", arg);
usage();
System.exit(1);
}
} else {
// it's the module specification
nameArgument = arg;
int cnt = argsLen - i - 1;
moduleArgs = new String[cnt];
System.arraycopy(args, i + 1, moduleArgs, 0, cnt);
break;
}
} catch (IndexOutOfBoundsException e) {
System.err.printf("Argument expected for option %s\n", arg);
usage();
System.exit(1);
}
}
if (modifyInPlace && ! addIndex) {
System.err.println("-modify requires -addindex");
usage();
System.exit(1);
}
if (addIndex) {
System.err.println("WARNING: -addindex is deprecated and may be removed in a future release");
if (nameArgument == null) {
System.err.println("-addindex requires a target JAR name");
usage();
System.exit(1);
}
if (modulePath != null) {
System.err.println("-mp may not be used with -addindex");
usage();
System.exit(1);
}
if (jaxpModuleName != null) {
System.err.println("-jaxpModuleName may not be used with -addindex");
usage();
System.exit(1);
}
if (classpathDefined) {
System.err.println("-cp or -classpath may not be used with -addindex");
usage();
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be used with -addindex");
usage();
System.exit(1);
}
if (jar) {
System.err.println("-jar may not be used with -addindex");
usage();
System.exit(1);
}
if (deps != null) {
System.err.println("-deps may not be used with -addindex");
usage();
System.exit(1);
}
if (defaultSecMgr) {
System.err.println("-secmgr may not be used with -addindex");
usage();
System.exit(1);
}
if (secMgrModule != null) {
System.err.println("-secmgrmodule may not be used with -addindex");
usage();
System.exit(1);
}
if (! addedProviders.isEmpty()) {
System.err.println("-add-provider may not be used with -addindex");
}
if (depTree) {
System.err.println("-deptree may not be used with -addindex");
usage();
System.exit(1);
}
JarFileResourceLoader.addInternalIndex(new File(nameArgument), modifyInPlace);
return;
}
if (deps != null && ! classDefined && ! classpathDefined) {
System.err.println("-deps may only be specified when -cp/-classpath or -class is in use");
System.exit(1);
}
// run the module
if (nameArgument == null) {
if (classDefined || classpathDefined) {
System.err.println("No class name specified");
} else if (jar) {
System.err.println("No JAR specified");
} else {
System.err.println("No module specified");
}
usage();
System.exit(1);
}
if (depTree) {
DependencyTreeViewer.print(new PrintWriter(System.out), nameArgument, LocalModuleFinder.getRepoRoots(true));
System.exit(0);
}
if(debuglog) {
// Install the StreamModuleLogger on System.out to capture bootstrap messages
Module.setModuleLogger(new StreamModuleLogger(System.out));
}
final ModuleLoader loader;
final ModuleLoader environmentLoader;
environmentLoader = DefaultBootModuleLoaderHolder.INSTANCE;
final Path rootPath = Paths.get("").toAbsolutePath();
final String moduleName;
final String className;
if (jar) {
loader = new ModuleLoader(new FileSystemClassPathModuleFinder(environmentLoader));
moduleName = rootPath.resolve(nameArgument).normalize().toString();
className = null;
} else if (classpathDefined || classDefined) {
final String[] items;
if (classpath != null) {
AccessController.doPrivileged(new PropertyWriteAction("java.class.path", classpath));
items = classpath.split(Pattern.quote(File.pathSeparator));
} else {
items = NO_STRINGS;
}
for (int i = 0; i < items.length; i++) {
items[i] = rootPath.resolve(items[i]).normalize().toString();
}
loader = new DelegatingModuleLoader(environmentLoader, new ClassPathModuleFinder(environmentLoader, items, deps, nameArgument));
moduleName = "";
className = null;
} else {
loader = environmentLoader;
final int idx = nameArgument.lastIndexOf('/');
if (idx != -1) {
moduleName = nameArgument.substring(0, idx);
className = nameArgument.substring(idx + 1);
} else {
moduleName = nameArgument;
className = null;
}
}
Module.initBootModuleLoader(environmentLoader);
if (jaxpModuleName != null) {
__JAXPRedirected.changeAll(jaxpModuleName, Module.getBootModuleLoader());
} else {
__JAXPRedirected.changeAll(moduleName, Module.getBootModuleLoader());
}
if (moduleName == null) {
return;
}
final Module module;
try {
module = loader.loadModule(moduleName);
} catch (ModuleNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
return;
}
final String ourJavaVersion = doPrivileged(new PropertyReadAction("java.specification.version", "1.6"));
final String requireJavaVersion = module.getProperty("jboss.require-java-version", ourJavaVersion);
final Pattern versionPattern = Pattern.compile("(?:1\\.)?(\\d+)");
final Matcher requireMatcher = versionPattern.matcher(requireJavaVersion);
final Matcher ourMatcher = versionPattern.matcher(ourJavaVersion);
if (requireMatcher.matches() && ourMatcher.matches() && Integer.parseInt(requireMatcher.group(1)) > Integer.parseInt(ourMatcher.group(1))) {
System.err.printf("This application requires Java specification version %s or later to run (this Java virtual machine implements specification version %s)%n", requireJavaVersion, ourJavaVersion);
System.exit(1);
}
ModularURLStreamHandlerFactory.addHandlerModule(module);
ModularContentHandlerFactory.addHandlerModule(module);
// at this point, having a security manager already installed will prevent correct operation.
final SecurityManager existingSecMgr = System.getSecurityManager();
if (existingSecMgr != null) {
System.err.println("An existing security manager was detected. You must use the -secmgr switch to start with a security manager.");
System.exit(1);
return; // not reached
}
try {
final Iterator iterator = module.loadService(Policy.class).iterator();
if (iterator.hasNext()) {
Policy.setPolicy(iterator.next());
}
} catch (Exception ignored) {}
// configure policy so that if SM is enabled, modules can still function
final ModulesPolicy policy = new ModulesPolicy(Policy.getPolicy());
Policy.setPolicy(policy);
if (secMgrModule != null) {
final Module loadedModule;
try {
loadedModule = environmentLoader.loadModule(secMgrModule);
} catch (ModuleNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
return;
}
final Iterator iterator = ServiceLoader.load(SecurityManager.class, loadedModule.getClassLoaderPrivate()).iterator();
if (iterator.hasNext()) {
System.setSecurityManager(iterator.next());
} else {
System.err.println("No security manager found in module " + secMgrModule);
System.exit(1);
}
}
if (defaultSecMgr) {
final Iterator iterator = module.loadService(SecurityManager.class).iterator();
if (iterator.hasNext()) {
System.setSecurityManager(iterator.next());
} else {
System.setSecurityManager(new SecurityManager());
}
}
final ModuleClassLoader bootClassLoader = module.getClassLoaderPrivate();
setContextClassLoader(bootClassLoader);
final String serviceName = getServiceName(bootClassLoader, "java.util.prefs.PreferencesFactory");
if (serviceName != null) {
final String old = System.setProperty("java.util.prefs.PreferencesFactory", serviceName);
try {
Preferences.systemRoot();
} finally {
if (old == null) {
System.clearProperty("java.util.prefs.PreferencesFactory");
} else {
System.setProperty("java.util.prefs.PreferencesFactory", old);
}
}
}
final String logManagerName = getServiceName(bootClassLoader, "java.util.logging.LogManager");
if (logManagerName != null) {
System.setProperty("java.util.logging.manager", logManagerName);
if (LogManager.getLogManager().getClass() == LogManager.class) {
System.err.println("WARNING: Failed to load the specified log manager class " + logManagerName);
} else {
Module.setModuleLogger(new JDKModuleLogger());
}
}
final String mbeanServerBuilderName = getServiceName(bootClassLoader, "javax.management.MBeanServerBuilder");
if (mbeanServerBuilderName != null) {
System.setProperty("javax.management.builder.initial", mbeanServerBuilderName);
// Initialize the platform mbean server
ManagementFactory.getPlatformMBeanServer();
}
for (String addedProvider : addedProviders) {
final int idx = addedProvider.indexOf('/');
if (idx != -1) {
final String provModule = addedProvider.substring(0, idx);
final String provClazz = addedProvider.substring(idx + 1);
final Class extends Provider> providerClass;
try {
providerClass = Class.forName(provClazz, false, environmentLoader.loadModule(provModule).getClassLoaderPrivate()).asSubclass(Provider.class);
// each provider needs permission to install itself
doPrivileged(new AddProviderAction(providerClass.getConstructor().newInstance()), getProviderContext(providerClass));
} catch (Exception e) {
Module.getModuleLogger().trace(e, "Failed to initialize a security provider");
}
} else {
final ModuleClassLoader classLoader = environmentLoader.loadModule(addedProvider).getClassLoaderPrivate();
final ServiceLoader