wouterdz
wouterdz

Reputation: 141

Shading using Spring Boot Maven not working properly

I want to be able to start my Spring application using a jar file. I make use of the spring boot maven plugin, but for some reason it doesn't package my resources properly. So if I create a jar file using mvn clean install (see pom.xml), it builds successfully but I get the following error when I run the application (using java -jar):

java.io.FileNotFoundException: file:\C:\Users\Wouter\Documents\Sparkling-Server\target\sparkling-server-1.0.jar!\BOOT-IN
F\classes!\config.json (The filename, directory name, or volume label syntax is incorrect)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileReader.<init>(Unknown Source)
        at com.sparkling.server.configuration.Configuration.loadConfig(Configuration.java:79)
        at com.sparkling.server.configuration.Configuration.<init>(Configuration.java:41)
        at com.sparkling.server.configuration.Configuration.getInstance(Configuration.java:101)
        at com.sparkling.server.configuration.MongoDBConfig.setupMongo(MongoDBConfig.java:30)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de.CGLIB$setupMongo$0(<generat
ed>)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de$$FastClassBySpringCGLIB$$35
83b6d3.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Configurati
onClassEnhancer.java:356)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de.setupMongo(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy
.java:162)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolv
er.java:588)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(Ab
stractAutowireCapableBeanFactory.java:1173)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutow
ireCapableBeanFactory.java:1067)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCap
ableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegis
try.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Configurati
onClassEnhancer.java:381)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de.setupMongo(<generated>)
        at com.sparkling.server.configuration.MongoDBConfig.mongoTemplate(MongoDBConfig.java:49)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de.CGLIB$mongoTemplate$1(<gene
rated>)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de$$FastClassBySpringCGLIB$$35
83b6d3.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Configurati
onClassEnhancer.java:356)
        at com.sparkling.server.configuration.MongoDBConfig$$EnhancerBySpringCGLIB$$e1ed07de.mongoTemplate(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy
.java:162)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolv
er.java:588)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(Ab
stractAutowireCapableBeanFactory.java:1173)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutow
ireCapableBeanFactory.java:1067)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCap
ableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegis
try.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueRes
olver.java:351)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionV
alueResolver.java:108)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAuto
wireCapableBeanFactory.java:1531)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCap
ableBeanFactory.java:1276)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCap
ableBeanFactory.java:553)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegis
try.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanF
actory.java:1138)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFac
tory.java:1066)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.injec
t(AutowiredAnnotationBeanPostProcessor.java:585)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(A
utowiredAnnotationBeanPostProcessor.java:366)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCap
ableBeanFactory.java:1264)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCap
ableBeanFactory.java:553)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegis
try.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListable
BeanFactory.java:761)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplic
ationContext.java:866)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext
.java:122)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
        at com.sparkling.server.Main.main(Main.java:15)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

While this configuration file can be found when running the application in IntelliJ. Furthermore if I decompile the jar it does seem to be present.

Decompiled jar

And here my pom.xml and Configuration class:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.sparkling</groupId>
<artifactId>sparkling-server</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jasypt</groupId>
        <artifactId>jasypt</artifactId>
        <version>1.9.2</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.5.6</version>
    </dependency>
</dependencies>

<properties>
    <java.version>1.8</java.version>
</properties>


<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </pluginRepository>
</pluginRepositories>

package com.sparkling.server.configuration;

import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;


public class Configuration {

    //static instances
    private static Configuration instance;
    private static Logger logger = Logger.getLogger(Configuration.class.getName());

    //configuration information
    private boolean loaded = false;
    private String CONFIG_NAME = "config.json";
    private JSONObject configObject;

    /**
     * Constructs a new config class.
     */
    private Configuration() {
        try {
            loadConfig();
        } catch (IOException fExcp) {
            fExcp.printStackTrace();
            logger.error("There was a problem loading the config file.");
        } catch (ParseException pExcp) {
            logger.error("A problem occurred parsing the config file.");
        }
    }

    /**
     * Returns the repos configuration.
     * @param element the element you want to retrieve.
     * @return a JSONObject.
     */
    public JSONObject getElement(String element) {
        if (isLoaded()) {
            return (JSONObject) configObject.get(element);
        } else {
            logger.error("Tried to retrieve database config, but config is not loaded.");
            return null;
        }
    }

    /**
     * Loads the config file into a JSON object.
     *
     * @throws ParseException if the file can't be parsed.
     * @throws IOException    if there is a problem loading the file.
     */
    private void loadConfig() throws ParseException, IOException {
        URL configURL = new ClassPathResource(CONFIG_NAME).getURL();

        if (configURL == null) {
            throw new FileNotFoundException();
        }

        File file = new File(configURL.getFile());
        JSONParser parser = new JSONParser();
        configObject = (JSONObject) parser.parse(new FileReader(file));
        this.loaded = true;

        logger.info("Configuration file loaded.");
    }

    /**
     * Check if the config is loaded.
     *
     * @return if the config is loaded.
     */
    public boolean isLoaded() {
        return loaded;
    }

    /**
     * Get an instance of the configuration class.
     *
     * @return the config instance.
     */
    public static Configuration getInstance() {
        if (instance == null)
            instance = new Configuration();
        return instance;
    }

}

So do I wrongly load the configuration resource or should I change my shading/packaging configuration?

Thanks in advance!

Edit: This issued was solved by instead of getting the File, getting the InputStream (using Resource resource = new ClassPathResource("/config.json");) of the File and get that parsed.

Upvotes: 0

Views: 479

Answers (1)

Praneeth Ramesh
Praneeth Ramesh

Reputation: 3564

Resource resource = new ClassPathResource("/config.json"); This would work in your case because when u say backslash before the file name it means to look up the root of the classpath. But when u say just config.json its relative path lookup.

If your config file is inside src/main/resources of your application then maven puts into the root folder of the classpath/jar hence you need to use backslash.

Upvotes: 1

Related Questions