Skip to content

Commit

Permalink
WELD-2122 Support libs on Tomcat with unpackWARs=false
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba committed Apr 7, 2016
1 parent c0012db commit c4c1d74
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.jboss.weld.environment.util.URLUtils.PROCOTOL_HTTPS;
import static org.jboss.weld.environment.util.URLUtils.PROCOTOL_JAR;
import static org.jboss.weld.environment.util.URLUtils.PROTOCOL_FILE_PART;
import static org.jboss.weld.environment.util.URLUtils.PROTOCOL_WAR_PART;

import java.io.File;
import java.lang.reflect.Field;
Expand Down Expand Up @@ -83,7 +84,7 @@ public List<ScanResult> scan() {

/**
* @param url
* @return
* @return an adapted bean archive reference
* @throws URISyntaxException
*/
protected String getBeanArchiveReference(URL url) {
Expand All @@ -99,9 +100,8 @@ protected String getBeanArchiveReference(URL url) {
if(PROCOTOL_FILE.equals(url.getProtocol())) {
// Adapt file URL, e.g. "file:///home/weld/META-INF/beans.xml" becomes "/home/weld"
ref = new File(uri.getSchemeSpecificPart()).getParentFile().getParent();

} else if(PROCOTOL_JAR.equals(url.getProtocol())) {
// Adapt JAR file URL, e.g. "jar:file:/home/duke/duke.jar!/META-INF/beans.xml" becomes "/home/duke/duke.jar"
// Attempt to adapt JAR file URL, e.g. "jar:file:/home/duke/duke.jar!/META-INF/beans.xml" becomes "/home/duke/duke.jar"
// NOTE: Some class loaders may support nested jars, e.g. "jar:file:/home/duke/duke.jar!/lib/foo.jar!/META-INF/beans.xml" becomes
// "/home/duke/duke.jar!/lib/foo.jar"

Expand All @@ -125,6 +125,10 @@ protected String getBeanArchiveReferenceForJar(String path, URL fallback) {
if (path.startsWith(PROTOCOL_FILE_PART)) {
return path.substring(PROTOCOL_FILE_PART.length());
}
if (path.startsWith(PROTOCOL_WAR_PART)) {
// E.g. for Tomcat with unpackWARs=false return war:file:/webapp.war/WEB-INF/lib/foo.jar
return path;
}
// jar:http:
if (path.startsWith(PROCOTOL_HTTP) || path.startsWith(PROCOTOL_HTTPS)) {
// WebStart support: get path to local cached copy of remote JAR file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ public class URLUtils {

public static final String PROCOTOL_FILE = "file";
public static final String PROCOTOL_JAR = "jar";
public static final String PROCOTOL_WAR = "war";
public static final String PROCOTOL_HTTP = "http";
public static final String PROCOTOL_HTTPS = "https";
public static final String PROTOCOL_FILE_PART = PROCOTOL_FILE + ":";
public static final String PROTOCOL_WAR_PART = PROCOTOL_WAR + ":";
// according to JarURLConnection api doc, the separator is "!/"
public static final String JAR_URL_SEPARATOR = "!/";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@ public class JandexServletContextBeanArchiveHandler extends ServletContextBeanAr

private final Indexer indexer = new Indexer();

private final ServletContext servletContext;

/**
* @param servletContext
*/
public JandexServletContextBeanArchiveHandler(ServletContext servletContext) {
super(servletContext);
this.servletContext = servletContext;
}

@Override
Expand All @@ -50,7 +47,6 @@ public BeanArchiveBuilder handle(String path) {
if (builder == null) {
return null;
}

builder.setAttribute(Jandex.INDEX_ATTRIBUTE_NAME, buildIndex());
return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
*/
package org.jboss.weld.environment.servlet.deployment;

import static org.jboss.weld.environment.util.URLUtils.PROTOCOL_WAR_PART;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletContext;

Expand All @@ -26,17 +33,20 @@
import org.jboss.weld.environment.util.Files;

/**
* Handles the paths to resources within a web application. It's used if a WAR archive is not extracted to the file system.
* Handles the paths to resources within a web application if a WAR archive is not extracted to the file system.
* <p>
* For {@code WEB-INF/classes}, {@link ServletContext#getResourcePaths(String)} is used. For libraries, only {@code war} protocol is supported.
*
* @author Martin Kouba
* @author Thomas Meyer
*/
public class ServletContextBeanArchiveHandler implements BeanArchiveHandler {

protected static final String SLASH = "/";

protected static final String DOT = ".";

private final ServletContext servletContext;
protected final ServletContext servletContext;

/**
* @param servletContext
Expand All @@ -47,13 +57,24 @@ public ServletContextBeanArchiveHandler(ServletContext servletContext) {

@Override
public BeanArchiveBuilder handle(String path) {
if (!path.equals(WebAppBeanArchiveScanner.WEB_INF_CLASSES)) {
return null;
if (path.equals(WebAppBeanArchiveScanner.WEB_INF_CLASSES)) {
BeanArchiveBuilder builder = new BeanArchiveBuilder();
handleResourcePath(path, path, builder);
return builder;
} else if (path.startsWith(PROTOCOL_WAR_PART)) {
try {
URL url = new URL(path);
InputStream in = url.openStream();
if (in != null) {
BeanArchiveBuilder builder = new BeanArchiveBuilder();
handleLibrary(url, in, builder);
return builder;
}
} catch (IOException e) {
WeldServletLogger.LOG.cannotHandleLibrary(path, e);
}
}

BeanArchiveBuilder builder = new BeanArchiveBuilder();
handleResourcePath(path, path, builder);
return builder;
return null;
}

protected void add(String rootPath, String subpath, BeanArchiveBuilder builder) {
Expand All @@ -64,10 +85,8 @@ protected void add(String rootPath, String subpath, BeanArchiveBuilder builder)
}

private void handleResourcePath(String rootPath, String resourcePath, BeanArchiveBuilder builder) {

WeldServletLogger.LOG.debugv("Handle resource path: {0}", resourcePath);
Set<String> subpaths = servletContext.getResourcePaths(resourcePath);

if (subpaths != null && !subpaths.isEmpty()) {
for (String subpath : subpaths) {
if (subpath.endsWith(SLASH)) {
Expand All @@ -80,6 +99,18 @@ private void handleResourcePath(String rootPath, String resourcePath, BeanArchiv
}
}

private void handleLibrary(URL url, InputStream in, BeanArchiveBuilder builder) throws IOException {
WeldServletLogger.LOG.debugv("Handle library: {0}", url);
try (ZipInputStream zip = new ZipInputStream(in)) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
if (Files.isClass(entry.getName())) {
builder.addClass(Files.filenameToClassname(entry.getName()));
}
}
}
}

private String toClassName(String rootPath, String resourcePath) {
// Remove WEB-INF/classes part, suffix and replace slashes with dots
return resourcePath.substring(rootPath.length() + 1, resourcePath.lastIndexOf(Files.CLASS_FILE_EXTENSION)).replace(SLASH, DOT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ public interface WeldServletLogger extends WeldEnvironmentLogger {
@Message(id = 1029, value = "org.jboss.weld.environment.servlet.Listener is in an inconsistent state - Weld Servlet cannot be shut down properly")
void noServletLifecycleToDestroy();

// Messages with ids 1030 and 1031 were removed
@LogMessage(level = Level.ERROR)
@Message(id = 1030, value = "Error handling library: {0}.", format = Format.MESSAGE_FORMAT)
void cannotHandleLibrary(Object path, @Cause Throwable cause);

}

0 comments on commit c4c1d74

Please sign in to comment.