This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/tomcat-maven-plugin.git
The following commit(s) were added to refs/heads/trunk by this push:
new 4a5f83f Merge code from PR#30
4a5f83f is described below
commit 4a5f83fc302c14436361031b1d112efe53431040
Author: remm <[email protected]>
AuthorDate: Thu Feb 5 16:12:11 2026 +0100
Merge code from PR#30
Rewrite resource code for Tomcat 9.
Submitted by Karl von Randow.
---
.../maven/plugin/tomcat/run/AbstractRunMojo.java | 84 -----
.../tomcat/maven/plugin/tomcat/run/RunMojo.java | 379 +++++----------------
2 files changed, 77 insertions(+), 386 deletions(-)
diff --git
a/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
b/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
index 1ef2eb2..887cee1 100644
---
a/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
+++
b/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
@@ -695,11 +695,6 @@ public abstract class AbstractRunMojo
Context context = container.addWebapp( contextPath, baseDir );
- context.setResources(
- new MyDirContext( new File(
project.getBuild().getOutputDirectory() ).getAbsolutePath(), //
- getPath(), //
- getLog() ) );
-
if ( useSeparateTomcatClassLoader )
{
context.setParentClassLoader( getTomcatClassLoader() );
@@ -790,85 +785,6 @@ public abstract class AbstractRunMojo
}
- protected static class MyDirContext
- extends StandardRoot
- {
- String buildOutputDirectory;
-
- String webAppPath;
-
- WebResourceSet webResourceSet;
-
- Log log;
-
- MyDirContext( String buildOutputDirectory, String webAppPath, Log log )
- {
-
- this.buildOutputDirectory = buildOutputDirectory;
- this.webAppPath = webAppPath;
- this.log = log;
- }
-
- @Override
- public WebResource getResource( String path )
- {
-
- log.debug( "MyDirContext#getResource: " + path );
- if ( "/WEB-INF/classes".equals( path ) )
- {
- return new FileResource( this, this.webAppPath, new File(
this.buildOutputDirectory ), true, null);
- }
-
- File file = new File( path );
- if ( file.exists() )
- {
- return new FileResource( this, this.webAppPath, file, true,
null);
- }
- WebResource webResource = super.getResource( path );
- return webResource;
- }
-
-
- @Override
- public WebResource getClassLoaderResource( String path )
- {
- log.debug( "MyDirContext#getClassLoaderResource: " + path );
- // here get resources from various paths
- return super.getClassLoaderResource( path );
- }
-
-
- @Override
- public WebResource[] listResources( String path )
- {
- log.debug( "MyDirContext#listResources: " + path );
- return super.listResources( path );
- }
-
- @Override
- public WebResource[] getClassLoaderResources( String path )
- {
- log.debug( "MyDirContext#getClassLoaderResources: " + path );
- return super.getClassLoaderResources( path );
- }
-
- @Override
- public WebResource[] getResources( String path )
- {
- log.debug( "MyDirContext#getResources: " + path );
- return super.getResources( path );
- }
-
- @Override
- protected WebResource[] getResourcesInternal( String path, boolean
useClassLoaderResources )
- {
- log.debug( "MyDirContext#getResourcesInternal: " + path );
- return super.getResourcesInternal( path, useClassLoaderResources );
- }
-
-
- }
-
/**
* Gets the webapp loader to run this web application under.
*
diff --git
a/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
b/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
index b55f9ba..628df5a 100644
---
a/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
+++
b/tomcat-main-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
@@ -22,6 +22,7 @@ import org.apache.catalina.Context;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.loader.WebappLoader;
+import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.EmptyResource;
import org.apache.catalina.webresources.FileResource;
import org.apache.catalina.webresources.FileResourceSet;
@@ -31,6 +32,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
@@ -314,187 +316,96 @@ public class RunMojo
final List<String> classLoaderEntries =
classLoaderEntriesCalculatorResult.getClassPathEntries();
final List<File> tmpDirectories =
classLoaderEntriesCalculatorResult.getTmpDirectories();
+ /* Add jars */
final List<String> jarPaths = extractJars( classLoaderEntries );
-
- List<URL> urls = new ArrayList<>( jarPaths.size() );
-
- for ( String jarPath : jarPaths )
- {
- try
- {
- urls.add( new File( jarPath ).toURI().toURL() );
- }
- catch ( MalformedURLException e )
- {
- throw new MojoExecutionException( e.getMessage(), e );
+ for (String jarPath : jarPaths) {
+ File f = new File(jarPath);
+ if (f.exists()) {
+ /* We add the jar as a file under /WEB-INF/lib and Tomcat
takes care of creating a JarResourceSet for its classes and
+ for its resources in /META-INF/resources as
appropriate. Basically it hooks into Tomcat's usual handling.
+ */
+ getLog().debug("Adding jar resource: " +
f.getAbsolutePath());
+ FileResourceSet fileResourceSet = new
FileResourceSet(context.getResources(), "/WEB-INF/lib/" + f.getName(),
f.getAbsolutePath(), "/");
+ context.getResources().addPostResources(fileResourceSet);
}
}
- getLog().debug( "classLoaderEntriesCalculator urls: " + urls );
-
- final URLClassLoader urlClassLoader = new URLClassLoader(
urls.toArray( new URL[urls.size()] ) );
+ /* Add build directories */
+ getLog().debug("Adding classes resource: " + new
File(project.getBuild().getOutputDirectory()).getAbsolutePath());
+ DirResourceSet webinfClassesResources = new
DirResourceSet(context.getResources(), "/WEB-INF/classes", new
File(project.getBuild().getOutputDirectory()).getAbsolutePath(), "/") {
- final ClassRealm pluginRealm = getTomcatClassLoader();
-
- context.setResources(
- new MyDirContext( new File(
project.getBuild().getOutputDirectory() ).getAbsolutePath(), //
- getPath(), //
- getLog() )
- {
- @Override
- public WebResource getClassLoaderResource( String path )
- {
-
- log.debug( "RunMojo#getClassLoaderResource: " + path );
- URL url = urlClassLoader.getResource(
StringUtils.removeStart( path, "/" ) );
- // search in parent (plugin) classloader
- if ( url == null )
- {
- url = pluginRealm.getResource(
StringUtils.removeStart( path, "/" ) );
- }
-
- if ( url == null )
- {
- // try in reactors
- List<WebResource> webResources =
findResourcesInDirectories( path, //
-
classLoaderEntriesCalculatorResult.getBuildDirectories() );
-
- // so we return the first one
- if ( !webResources.isEmpty() )
- {
- return webResources.get( 0 );
+ @Override
+ public WebResource getResource(String path) {
+ /* We need to juggle with /META-INF/beans.xml as Weld's
WebAppBeanArchiveScanner has special handling
+ for /WEB-INF/classes that doesn't work with this.
+ That is because it first finds _all_ resources
/META-INF/beans.xml and it ends up with the URLs to those
+ resources, which are all file-system URLs, and then looks
for /WEB-INF/classes in the URL, which we don't
+ have as our files are in the Maven target directory.
+ */
+ if ("/WEB-INF/classes/META-INF/beans.xml".equals(path)) {
+ getLog().info("Rejecting request for
/WEB-INF/classes/META-INF/beans.xml for Weld compatibility. beans.xml can be
found at /WEB-INF/beans.xml");
+ return new EmptyResource(getRoot(), path);
+ } else if ("/WEB-INF/beans.xml".equals(path)) {
+ WebResource beans = super.getResource(path);
+ if (!beans.exists()) {
+ beans =
super.getResource("/WEB-INF/classes/META-INF/beans.xml");
+ if (beans.exists()) {
+ getLog().info("Returning
/WEB-INF/classes/META-INF/beans.xml for request of /WEB-INF/beans.xml for Weld
compatibility");
}
}
-
- if ( url == null )
- {
- return new EmptyResource( this, getPath() );
- }
-
- return urlToWebResource( url, path );
- }
-
- @Override
- public WebResource getResource( String path )
- {
- log.debug( "RunMojo#getResource: " + path );
- return super.getResource( path );
- }
-
- @Override
- public WebResource[] getResources( String path )
- {
- log.debug( "RunMojo#getResources: " + path );
- return super.getResources( path );
- }
-
- @Override
- protected WebResource[] getResourcesInternal( String path,
boolean useClassLoaderResources )
- {
- log.debug( "RunMojo#getResourcesInternal: " + path );
- return super.getResourcesInternal( path,
useClassLoaderResources );
+ return beans;
+ } else {
+ return super.getResource(path);
}
+ }
+
+ };
+ context.getResources().addPreResources(webinfClassesResources);
- @Override
- public WebResource[] getClassLoaderResources( String path )
- {
- try
- {
- Enumeration<URL> enumeration =
- urlClassLoader.findResources(
StringUtils.removeStart( path, "/" ) );
- List<URL> urlsFound = new ArrayList<>();
- List<WebResource> webResources = new ArrayList<>();
- while ( enumeration.hasMoreElements() )
- {
- URL url = enumeration.nextElement();
- urlsFound.add( url );
- webResources.add( urlToWebResource( url, path
) );
- }
- log.debug(
- "RunMojo#getClassLoaderResources: " + path + "
found : " + urlsFound.toString() );
-
- webResources.addAll( findResourcesInDirectories(
path,
-
classLoaderEntriesCalculatorResult.getBuildDirectories() ) );
+ for (final String buildDirectory :
classLoaderEntriesCalculatorResult.getBuildDirectories()) {
+ if
(buildDirectory.equals(project.getBuild().getOutputDirectory())) {
+ continue;
+ }
- return webResources.toArray( new
WebResource[webResources.size()] );
+ final File buildDirectoryFile = new File(buildDirectory);
+ getLog().debug("Adding additional classes resource: " +
buildDirectoryFile.getAbsolutePath());
+ DirResourceSet otherClassesResources = new
DirResourceSet(context.getResources(), "/WEB-INF/classes",
buildDirectoryFile.getAbsolutePath(), "/");
+ context.getResources().addPreResources(otherClassesResources);
+ }
+ /* Support the maven-war-plugin's webResources configuration to
add resources */
+ final Plugin warPlugin = (Plugin)
project.getBuild().getPluginsAsMap().get("org.apache.maven.plugins:maven-war-plugin");
+ if (warPlugin != null && warPlugin.getConfiguration() instanceof
Xpp3Dom) {
+ final Xpp3Dom cfg = (Xpp3Dom) warPlugin.getConfiguration();
+ Xpp3Dom webResources = cfg.getChild("webResources");
+ if (webResources != null) {
+ Xpp3Dom[] resources = webResources.getChildren("resource");
+ for (Xpp3Dom resource : resources) {
+ Xpp3Dom directoryNode = resource.getChild("directory");
+ if (directoryNode == null) {
+ continue;
}
- catch ( IOException e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
+ final String directory = directoryNode.getValue();
+ Xpp3Dom targetPathNode =
resource.getChild("targetPath");
+ final String targetPath = targetPathNode != null ? "/"
+ targetPathNode.getValue() : "/";
- private List<WebResource> findResourcesInDirectories(
String path, List<String> directories )
- {
- try
- {
- List<WebResource> webResources = new ArrayList<>();
-
- for ( String directory : directories )
- {
-
- File file = new File( directory, path );
- if ( file.exists() )
- {
- webResources.add( urlToWebResource(
file.toURI().toURL(), path ) );
- }
-
- }
-
- return webResources;
+ Xpp3Dom filtering = resource.getChild("filtering");
+ if (filtering != null &&
"true".equals(filtering.getValue())) {
+ /* We don't support filtered resources */
+ getLog().warn("Cannot support filtered
web-resource, not adding: " + directory);
+ continue;
}
- catch ( MalformedURLException e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
-
-
- private WebResource urlToWebResource( URL url, String path
)
- {
- JarFile jarFile = null;
-
- try
- {
- // url.getFile is
- //
file:/Users/olamy/mvn-repo/org/springframework/spring-web/4.0.0.RELEASE/spring-web-4.0.0.RELEASE.jar!/org/springframework/web/context/ContextLoaderListener.class
- int idx = url.getFile().indexOf( '!' );
+ File directoryFile =
directory.startsWith(File.separator) ? new File(directory) : new
File(project.getBasedir(), directory);
+ DirResourceSet dirResourceSet = new
DirResourceSet(context.getResources(), targetPath,
directoryFile.getAbsolutePath(), "/");
+ dirResourceSet.setStaticOnly(true);
+
context.getResources().addPostResources(dirResourceSet);
- if ( idx >= 0 )
- {
- String filePath = StringUtils.removeStart(
url.getFile().substring( 0, idx ), "file:" );
-
- jarFile = new JarFile( filePath );
- JarResourceSet resourceSet = new
JarResourceSet(this, filePath, "/", filePath);
-
- JarEntry jarEntry = jarFile.getJarEntry(
StringUtils.removeStart( path, "/" ) );
-
- return new JarResource( resourceSet, //
- getPath(), //
-
url.getPath().substring( 0, idx ), //
- jarEntry);
- }
- else
- {
- return new FileResource( this, webAppPath, new
File( url.getFile() ), true, null);
- }
-
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- finally
- {
- IOUtils.closeQuietly( jarFile );
- }
+ getLog().debug("Adding additional static resources at
\"" + targetPath + "\": " + directoryFile.getAbsolutePath());
}
-
-
- } );
+ }
+ }
Runtime.getRuntime().addShutdownHook( new Thread()
{
@@ -514,142 +425,6 @@ public class RunMojo
}
}
} );
-
- if ( classLoaderEntries != null )
- {
- WebResourceSet webResourceSet = new FileResourceSet()
- {
- @Override
- public WebResource getResource( String path )
- {
-
- if ( StringUtils.startsWithIgnoreCase( path,
"/WEB-INF/LIB" ) )
- {
- File file = new File(
StringUtils.removeStartIgnoreCase( path, "/WEB-INF/LIB" ) );
- return new FileResource( context.getResources(),
getPath(), file, true, null);
- }
- if ( StringUtils.equalsIgnoreCase( path,
"/WEB-INF/classes" ) )
- {
- return new FileResource( context.getResources(),
getPath(),
- new File(
project.getBuild().getOutputDirectory() ), true, null);
- }
-
- File file = new File(
project.getBuild().getOutputDirectory(), path );
- if ( file.exists() )
- {
- return new FileResource( context.getResources(),
getPath(), file, true, null);
- }
-
- //if ( StringUtils.endsWith( path, ".class" ) )
- {
- // so we search the class file in the jars
- for ( String jarPath : jarPaths )
- {
- File jar = new File( jarPath );
- if ( !jar.exists() )
- {
- continue;
- }
-
- try
- {
- JarResourceSet resourceSet = new
JarResourceSet(context.getResources(), jarPath, "/", jarPath);
- JarFile jarFile = new JarFile( jar );
- JarEntry jarEntry =
- (JarEntry) jarFile.getEntry(
StringUtils.removeStart( path, "/" ) );
- if ( jarEntry != null )
- {
- return new JarResource( resourceSet, //
- getPath(), //
-
jar.toURI().toString(), //
- jarEntry);
- }
- }
- catch ( IOException e )
- {
- getLog().debug( "skip error building jar
file: " + e.getMessage(), e );
- }
-
- }
- }
-
- return new EmptyResource( null, path );
- }
-
- @Override
- public String[] list( String path )
- {
- if ( StringUtils.startsWithIgnoreCase( path,
"/WEB-INF/LIB" ) )
- {
- return jarPaths.toArray( new
String[jarPaths.size()] );
- }
- if ( StringUtils.equalsIgnoreCase( path,
"/WEB-INF/classes" ) )
- {
- return new String[]{ new File(
project.getBuild().getOutputDirectory() ).getPath() };
- }
- return super.list( path );
- }
-
- @Override
- public Set<String> listWebAppPaths( String path )
- {
-
- if ( StringUtils.equalsIgnoreCase( "/WEB-INF/lib/",
path ) )
- {
- // adding outputDirectory as well?
- return new HashSet<>( jarPaths );
- }
-
- File filePath = new File( getWarSourceDirectory(),
path );
-
- if ( filePath.isDirectory() )
- {
- Set<String> paths = new HashSet<>();
-
- String[] files = filePath.list();
- if ( files == null )
- {
- return paths;
- }
-
- for ( String file : files )
- {
- paths.add( path + file );
- }
-
- return paths;
-
- }
- else
- {
- return Collections.emptySet();
- }
- }
-
- @Override
- public boolean mkdir( String path )
- {
- return super.mkdir( path );
- }
-
- @Override
- public boolean write( String path, InputStream is, boolean
overwrite )
- {
- return super.write( path, is, overwrite );
- }
-
- @Override
- protected void checkType( File file )
- {
- //super.checkType( file );
- }
-
-
- };
-
- context.getResources().addJarResources( webResourceSet );
- }
-
}
catch ( TomcatRunException e )
{
@@ -660,7 +435,7 @@ public class RunMojo
/**
- * extract List of path which are files (removing directories from the
initial list)
+ * extract List of path which are jar files
*
* @param classLoaderEntries
* @return
@@ -669,7 +444,7 @@ public class RunMojo
throws MojoExecutionException
{
- List<String> jarPaths = new ArrayList<>();
+ List<String> jarPaths = new ArrayList<String>();
try
{
@@ -677,7 +452,7 @@ public class RunMojo
{
URI uri = new URI( classLoaderEntry );
File file = new File( uri );
- if ( !file.isDirectory() )
+ if ( !file.isDirectory() &&
StringUtils.endsWithIgnoreCase(file.getName(), ".jar"))
{
jarPaths.add( file.getAbsolutePath() );
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]