https://bz.apache.org/bugzilla/show_bug.cgi?id=66491

            Bug ID: 66491
           Summary: NullPointerException when resolving webapp JARs as
                    resources
           Product: Tomcat 10
           Version: 10.1.6
          Hardware: PC
                OS: Mac OS X 10.1
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: mmoay...@apache.org
  Target Milestone: ------

I am running a Spring Boot 3.0.3 web application with an embedded Apache Tomcat
10.1.6 container on JDK 17. Spring Boot 3.0.3 officially supports Tomcat 10.1.5
and I decided to upgrade to experiment. 

My application ultimately produces a WAR file and can be run as an executable
WAR file using the likes of "java -jar...". 

When the app runs, the following exception shows up:

Caused by: java.util.concurrent.ExecutionException:
org.apache.catalina.LifecycleException: Failed to start component
[org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory$LoaderHidingResourceRoot@17b37e9a]
        at
java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
        at
org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:878)
        ... 37 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component
[org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory$LoaderHidingResourceRoot@17b37e9a]
        at
org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
        at
org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:4566)
        at
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4699)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332)
        at
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at
org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at
java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
        at
org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:871)
        ... 37 more
Caused by: java.lang.NullPointerException: Cannot invoke
"java.net.URL.getProtocol()" because "url" is null
        at
org.apache.catalina.webresources.StandardRoot$BaseLocation.<init>(StandardRoot.java:815)
        at
org.apache.catalina.webresources.StandardRoot.createWebResourceSet(StandardRoot.java:357)
        at
org.apache.catalina.webresources.StandardRoot.processWebInfLib(StandardRoot.java:588)
        at
org.apache.catalina.webresources.StandardRoot.startInternal(StandardRoot.java:721)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        ... 46 more

If it helps, you can also see this failure in action here:
https://github.com/mmoayyed/cas/actions/runs/4269310213/jobs/7432837455 

This is not the case with Apache Tomcat 10.1.5 (which is what Spring Boot 3.0.3
officially supports as of this writing) I was not able to exactly pinpoint what
might have changed, but debugging through the code and following stack-trace I
am able to track it down to this block:

    protected void processWebInfLib() throws LifecycleException {
        WebResource[] possibleJars = listResources("/WEB-INF/lib", false);

        for (WebResource possibleJar : possibleJars) {
            if (possibleJar.isFile() && possibleJar.getName().endsWith(".jar"))
{
                createWebResourceSet(ResourceSetType.CLASSES_JAR,
"/WEB-INF/classes", possibleJar.getURL(), "/");
            }
        }
    }


The issue stems from the fact that "possibleJar.getURL()" returns null. The
getURL() method does the following:


    @Override
    public URL getURL() {
        String url = baseUrl + URLEncoder.DEFAULT.encode(resource.getName(),
StandardCharsets.UTF_8);
        try {
            return new URI(url).toURL();
        } catch (MalformedURLException | URISyntaxException e) {
            if (getLog().isDebugEnabled()) {
                getLog().debug(sm.getString("fileResource.getUrlFail", url),
e);
            }
            return null;
        }
    }

The "url" that is processed above has the prefix "war:", which I think is
causing this failure. 

Please note that deploy the web application into an standalone external tomcat
distribution works OK. This appears to mainly be an issue with the embedded
tomcat and WARs.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to