spring-boot-devtools outputs error message "Ignoring Class-Path entry..."

Created on 20 Jul 2017  路  6Comments  路  Source: spring-projects/spring-boot

to test some features of spring-boot-devtools, I created a spring boot app using spring boot 1.5.3.RELEASE from Spring Initializr, before writing anything I ran this app, but lines of red error message showed up:
image
it seemed that something is wrong with this fresh app, so I checked my pom file and tried to find the dependencies mentioned in the error message, with the help of IDEA I generated a maven diagram:

123

jaxb-api was transitively introduced by a dependency mssql-jdbc added by Spring Initializr, but the error message says that

D:.m2\repository\com\sunxmlbind\jaxb-impl\2.2.3-1\jaxb-api.jar does not exist

apparently the groupId of jaxb-api.jar is wrong, to figure out what happened, I spent some time debugging spring-boot-devtools, and traced the source of above mentioned error message, here is what happened:

private static List<URL> getUrlsFromManifestClassPathAttribute(JarFile jarFile)
        throws IOException {
    Manifest manifest = jarFile.getManifest();
    if (manifest == null) {
        return Collections.<URL>emptyList();
    }
    String classPath = manifest.getMainAttributes()
            .getValue(Attributes.Name.CLASS_PATH);
    if (!StringUtils.hasText(classPath)) {
        return Collections.emptyList();
    }
    String[] entries = StringUtils.delimitedListToStringArray(classPath, " ");
    List<URL> urls = new ArrayList<>(entries.length);
    File parent = new File(jarFile.getName()).getParentFile();
    for (String entry : entries) {
        try {
            File referenced = new File(parent, entry);
            if (referenced.exists()) {
                urls.add(referenced.toURI().toURL());
            }
            else {
                System.err.println("Ignoring Class-Path entry " + entry + " found in "
                        + jarFile.getName() + " as " + referenced
                        + " does not exist");
            }
        }
        catch (MalformedURLException ex) {
            throw new IllegalStateException(
                    "Class-Path attribute contains malformed URL", ex);
        }
    }
    return urls;
}

devtools reads MANIFEST.MF from jaxb-impl-2.2.3.jar and extracts the Class-Path attribute from it, then split the content of Class-Path into entries each of which then used to build corresponding URL, the content of MANIFEST.MF is pasted below:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 1.5.0_22-b03 (Sun Microsystems Inc.)
Specification-Title: Java Architecture for XML Binding
Specification-Version: 2.2.2
Specification-Vendor: Oracle Corporation
Implementation-Title: JAXB Reference Implementation 
Implementation-Version: 2.2.3
Implementation-Vendor: Oracle Corporation
Implementation-Vendor-Id: com.sun
Extension-Name: com.sun.xml.bind
Build-Id: hudson-jaxb-ri-2.2.3-3
Class-Path: jaxb-api.jar activation.jar jsr173_1.0_api.jar jaxb1-impl.
 jar

Name: com.sun.xml.bind.v2.runtime
Implementation-Version: 2.2.3-hudson-jaxb-ri-2.2.3-3-

according to the logic of method getUrlsFromManifestClassPathAttribute, devtools tries to find jaxb-api.jar from the same directory where jaxb-impl-2.2.3.jar resides, but the correct groupId of jaxb-api is javax.xml.bind.

I also tried downgrading the version of spring boot from 1.5.3.RELEASE to 1.5.2.RELEASE, the error message disappeared, so I guess this is a bug of devtools ?

I checked the commits of org.springframework.boot.devtools.restart.ChangeableUrls, and found a commit which seemed to be an update for devtools.

is this a bug ? that red error message is pretty annoying, so I'm looking for a way to disable that.

thx in advance.

task

Most helpful comment

devtools tries to find jaxb-api.jar from the same directory where jaxb-impl-2.2.3.jar resides, but the correct groupId of jaxb-api is javax.xml.bind.

The group ID isn't relevant here. A Class-Path entry in a jar's manifest knows nothing of Maven or it's directory layout. The Class-Path manifest entry is a space-separated list of file system paths to other jars that should be added to the class path. Those paths are relative to the jar that contains the manifest with the Class-Path entry.

The manifest for jaxb-impl-2.2.3.jar is, arguably, a bit broken. It lists four jars, yet does nothing to ensure that they exist. That means that the class path is not precisely defined and can vary depending on whether or not a jar with a particular name exists alongside the jaxb-impl-2.2.3.jar. The error message is warning you that a jar that one of your application's dependencies is looking for does not exist.

Unfortunately, we can't use logging to reliably report this warning as ChangeableUrls is called very early and, crucially, before the logging system is initialized. That's ok if you're using Logback as it logs debug messages and higher by default, but if you're using Log4j2 you won't see anything as it log nothing by default.

That leaves us with 3 choices:

  1. Leave things as they are
  2. Remove the System.err output
  3. Continue using System.err but provide a switch to turn it on or off

3 feels overly complex, so we're left with 1 or 2.

All 6 comments

@allbutone Please don't spam people by mentioning them in issues for no apparent reason. If people want to be notified of new issues they can opt in by watching the repository.

@wilkinsona sorry, I'm a beginner on github, still learning new stuff, and don't know well about the rules. I'll fix that. thanks for your suggestion

devtools tries to find jaxb-api.jar from the same directory where jaxb-impl-2.2.3.jar resides, but the correct groupId of jaxb-api is javax.xml.bind.

The group ID isn't relevant here. A Class-Path entry in a jar's manifest knows nothing of Maven or it's directory layout. The Class-Path manifest entry is a space-separated list of file system paths to other jars that should be added to the class path. Those paths are relative to the jar that contains the manifest with the Class-Path entry.

The manifest for jaxb-impl-2.2.3.jar is, arguably, a bit broken. It lists four jars, yet does nothing to ensure that they exist. That means that the class path is not precisely defined and can vary depending on whether or not a jar with a particular name exists alongside the jaxb-impl-2.2.3.jar. The error message is warning you that a jar that one of your application's dependencies is looking for does not exist.

Unfortunately, we can't use logging to reliably report this warning as ChangeableUrls is called very early and, crucially, before the logging system is initialized. That's ok if you're using Logback as it logs debug messages and higher by default, but if you're using Log4j2 you won't see anything as it log nothing by default.

That leaves us with 3 choices:

  1. Leave things as they are
  2. Remove the System.err output
  3. Continue using System.err but provide a switch to turn it on or off

3 feels overly complex, so we're left with 1 or 2.

I also met the same problem,Looking forward to solve the problem

Thinking about it a little more, there's a fourth option: switch to System.out. I think that's the best compromise here.

This is a development tool so it doesn't strike me as a big deal that we have some log output there. Perhaps System.out feels more appropriate for this.

Was this page helpful?
0 / 5 - 0 ratings