Skip to content

Prevent Quartz XSD from being fetched from the Internet [SPR-13706] #18281

@spring-projects-issues

Description

@spring-projects-issues

Mathieu Lachance opened SPR-13706 and commented

Quartz offer classloading spi through the org.quartz.spi.ClassLoadHelper interface.

Spring implements ClassLoadHelper in the ResourceLoaderClassLoadHelper which is use as the default Quartz value for 'org.quartz.scheduler.classLoadHelper.class'.

When I'm deploying my application inside JBoss EAP 6.1 and/or Wildfly 8.2.1.Final, the "job_scheduling_data_2_0.xsd" is getting hit from the Internet because it failed to fetch it properly from the classpath.

XMLSchedulingDataProcessorPlugin::processFile(JobFile) -> XMLSchedulingDataProcessor(classLoadHelper) -> resolveSchemaSource()

try {
    is = classLoadHelper.getResourceAsStream(QUARTZ_XSD_PATH_IN_JAR);
}  finally {
    if (is != null) {
        inputSource = new InputSource(is);
        inputSource.setSystemId(QUARTZ_SCHEMA_WEB_URL);
        log.debug("Utilizing schema packaged in local quartz distribution jar.");
    }
    else {
        log.info("Unable to load local schema packaged in quartz distribution jar. Utilizing schema online at " + QUARTZ_SCHEMA_WEB_URL);
        return QUARTZ_SCHEMA_WEB_URL;
    }
        }

by enabling the org.quartz.xml.XMLSchedulingDataProcessor logger you'll see that inside a container the "Unable to load local schema packaged in quartz distribution jar" trace will appear.
This is especially problematic in production environment where generally machines do not have access to the Internet and/or a very limitated access for security reasons.

Here's our temporary workaround which involve of prefixing "classpath:" to any XSD resource:

public class ResourceLoaderHelper extends ResourceLoaderClassLoadHelper {

    private static final String XSD_FILE_EXTENSION = ".xsd";

    @Override
    public URL getResource(String name) {
        if (name != null && name.endsWith(XSD_FILE_EXTENSION) && !name.startsWith(CLASSPATH_URL_PREFIX)) {
            return super.getResource(CLASSPATH_URL_PREFIX.concat(name));
        } else {
            return super.getResource(name);
        }
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        if (name != null && name.endsWith(XSD_FILE_EXTENSION) && !name.startsWith(CLASSPATH_URL_PREFIX)) {
            return super.getResourceAsStream(CLASSPATH_URL_PREFIX.concat(name));
        } else {
            return super.getResourceAsStream(name);
        }
    }
}

This workaround always retreive the XSD resource properly from the classpath. This work, though, this is definitely ugly.

I would suggest instead of our ugly workaround to simply change the Spring implementation to:

  1. check if the resource is found using the original location
  2. if not, prefix "classpath:" to the original location, and check again
  3. if it is yet not found, just return null and fail with the current behavior.

Let me know if I've miss something.

Thanks,


Affects: 3.2.16, 4.2.2

Referenced from: commits 51f356f, 7c998a7, 6db6f23

Backported to: 3.2.17

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions