Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Issues in Creating a Single JAR Bundle With All Dependency JARs Nested Within

DZone's Guide to

Issues in Creating a Single JAR Bundle With All Dependency JARs Nested Within

The problem that happens is that if two or more dependent jar libraries contain the same file/artifact, then the last one wins the race in the fatjar bundle.

· Java Zone
Free Resource

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

If you’re implementing any projects with Spring and Gradle (for build), as your project grows you may run into this issue. Or you’ve landed on this page by searching on Google for “Unable to locate Spring NamespaceHandler for XML schema namespace” (your actual XML that it’s error-ing out may vary).

Either way, you’re in luck! Most likely, you’re using the fatjar Gradle plugin to create a single JAR for executing as “java -jar one-big-bundle.jar”. The problem that happens is that if two or more dependent jar libraries contain the same file/artifact, then the last one wins the race in the fatjar bundle.

Let me illustrate this with an example.

Let’s say that your project depends on Spring-Context and Spring-Core. Within each jar, there maybe resources that have a common name such as META-INF/spring.schemas and/or META-INF/spring.handler (To learn more about the two individual files and their purpose in Spring, click on the links). When the fatjar combines the two JAR file, depending upon who goes last, the version of the above two files may belong to one or the other library. What should happen in reality is that it merges the two files contents. They may be good for some files. But if you have a specific file in a format where you simply cannot concatenate the two files (such as a nested XML or JSON), simply combining the two files will not work. You may need to extend the Gradle plugin tasks to perform something selective and unique to your situation.

But if you ended up here after searching for “Unable to locate Spring NamespaceHandler for XML schema namespace” message, there is hope. You can simply, add the following to the fatJar Gradle plugin and problem is solved:

fatJarPrepareFiles {
  include 'META-INF/spring.handlers'
  include 'META-INF/spring.schemas'
}

A second option is to use a newer plugin called shadow. [User Guide]

...
apply plugin: 'com.github.johnrengelman.shadow'
...
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
    }
}
...
//For building a single jar with all dependencies run "gradlew shadowJar"
// Configure the shadow jar task
shadowJar {
    mergeServiceFiles()
}

jar {
    manifest {
        attributes 'Implementation-Title': 'DDNMon Job Service',
                'Implementation-Version': version,
                'Main-Class': 'com.ddn.ddnmon.jobservice.Application'
    }
}

Cheers!

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:
schema ,gradle ,java ,jar

Published at DZone with permission of Venkatt Guhesan, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}