Bug 57823

Summary: Server hangs if there is a colon on the start of the class path
Product: Tomcat 8 Reporter: gregh <gregh3269>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED WONTFIX    
Severity: normal CC: nitsan_daniel
Priority: P2    
Version: 8.0.21   
Target Milestone: ----   
Hardware: PC   
OS: Linux   

Description gregh 2015-04-16 16:14:46 UTC
I have a startup in /etc/rc.d/init.d script that uses the daemon  eg:

daemon --user $tomcatuser --pidfile=$pidfile $command start

The server was hanging when starting up. I traced it org.apache.catalina.startup.ContextConfig.java 

..
protected void processAnnotationsUrl(URL url, WebXml fragment,
            boolean handlesTypesOnly) {
       
        if (url == null) {
            // Nothing to do.
            return;
        } else if ("jar".equals(url.getProtocol())) {
            System.out.println(url.toExternalForm());
            processAnnotationsJar(url, fragment, handlesTypesOnly);
        } else if ("file".equals(url.getProtocol())) {
            try {
                System.out.println(url.toExternalForm());
                processAnnotationsFile(
                       new File(url.toURI()), fragment, handlesTypesOnly);
            } catch (URISyntaxException e) {
                log.error(sm.getString("contextConfig.fileUrl", url), e);
            }
        } else {
            log.error(sm.getString("contextConfig.unknownUrlProtocol",
                    url.getProtocol(), url));
        }

    }

Where it would hang trying to process this line file:/


file:/opt/apache-tomcat/apache-tomcat-8.0.21/lib/
jar:file:/opt/apache-tomcat/apache-tomcat-8.0.21/lib/mysql-connector-java-5.1.34.jar!/
file:/


The file:/ seems to be from a :/ (colon) on the class path, and the combination of running it from /etc/rc.d/init.d makes it not work.

Not working
-classpath :/opt/apache-tomcat/apache-tomcat-8.0.21/bin/bootstrap.jar:/opt/apache-tomcat/apache-tomcat-8.0.21/bin/tomcat-juli.jar

Working
-classpath /opt/apache-tomcat/apache-tomcat-8.0.21/bin/bootstrap.jar:/opt/apache-tomcat/apache-tomcat-8.0.21/bin/tomcat-juli.jar


I guess we need to check for file:/ some where in the processAnnotationsUrl procesing so we do not scan the whole server.

Cheers Greg
Comment 1 Mark Thomas 2015-04-22 18:43:41 UTC
An empty class path element is treated by the JVM as the current working directory.

The class path is normally only scanned when the JarScanner is explicitly configured with scanBootstrapClassPath="true".

I suspect that starting via the init.d script sets the current working directory to '/' which is why the change in behavior is observed.

I'm against adding code to skip "file:/" in the JarScanner since that is the start of a slippery slope where we get all sorts of suggestions for what should be skipped. In essence, this is a configuration error and needs to be fixed at source - where the class path is set. Tomcat has code that optionally adds a separator when appending entries to the class path depending on if it is currently set or not. This init.d script should have the same logic.

I looked at adding some sort of warning if scanning a class path location was too long but I'm not convinced that this problem affects enough users to justify adding the code (this is the first report I can recall in my 10+ years working on Tomcat). The general "take 3 thread dumps 10s apart and compare" advice appears (to me) to be good enough to handle this case.

Given the above, I'm resolving this as WONTFIX.
Comment 2 gregh 2015-04-23 06:58:09 UTC
This was the entry in the /etc/rc.d/init.d script that I have used for many years, 5,6,7.  This only happens in 8.

CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar

ie the CLASSPATH value in /etc/profile.d had been commented out.

Still, I think it should have some sanity check that it does not scan the root folder.
Comment 3 Christopher Schultz 2015-04-27 18:47:48 UTC
(In reply to gregh from comment #2)
> This was the entry in the /etc/rc.d/init.d script that I have used for many
> years, 5,6,7.  This only happens in 8.
> 
> CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar
> 
> ie the CLASSPATH value in /etc/profile.d had been commented out.
> 
> Still, I think it should have some sanity check that it does not scan the
> root folder.

Your script can easily check to see if $CLASSPATH is empty and then ignore it. Tomcat doesn't do any scanning of the CLASSPATH itself (meaning, no textual scanning of the actual string representing the system classpath) and so there's not really any appropriate place to do this checking, other than adding some new sanity check for this.

I agree with Mark's reticence to add a check for this; there are an infinite number of insane CLASSPATH entries, and we can't check for all of them.
Comment 4 gregh 2015-04-28 08:36:25 UTC
Agreed, there would be far too many permutations to check for, but not knowing that the colon causes it to hang is the key.  Without debugging tomcat I was stuck as it would not start and nothing in the logs.  Maybe add something to the upgrade guide?

Cheers Greg
Comment 5 Konstantin Kolinko 2015-12-27 14:20:15 UTC
*** Bug 58766 has been marked as a duplicate of this bug. ***