3

I really do not know what is wrong with my Spring configuration. Could you give me hand?

My code (simplified version):

App.java:

public class App {
public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    ctx.close();
}

}

Config.java:

@Configuration
@ComponentScan
public class Config {
    @Bean
    public JdbcOperations jdbcTemplate(DataSource ds) {
        return new JdbcTemplate(ds);
    }
}

pom file:

 <properties>

    <!-- Generic properties -->
    <java.version>1.6</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <!-- Spring -->
    <spring-framework.version>4.2.5.RELEASE</spring-framework.version>

    <!-- Hibernate / JPA -->
    <hibernate.version>4.2.1.Final</hibernate.version>

    <!-- Logging -->
    <logback.version>1.0.13</logback.version>
    <slf4j.version>1.7.5</slf4j.version>

    <!-- Test -->
    <junit.version>4.11</junit.version>

</properties>

<dependencies>
    <!-- Spring and Transactions -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>

    <!-- Logging with SLF4J & LogBack -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>

    <!-- Hibernate -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>


    <!-- Test Artifacts -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring-framework.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.185</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>App</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

My folder structure:

After I maven package it, when I run the jar I got:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/annotation/AnnotationConfigApplicationContext
        at App.main(App.java:10)
Caused by: java.lang.ClassNotFoundException: org.springframework.context.annotation.AnnotationConfigApplicationContext
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

in which, the line 10 is the AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

In addition: I am writing the code when I was wathcing a spring tutorial:Spring Framework Tutorial 4: Database programming with JdbcTemplate

And his source code is at:github The only difference with the source code is that I added the MainClass in the pom file.

Thank you so much!
Sincerely

Spider
  • 1,380
  • 4
  • 22
  • 42

3 Answers3

3

The reason for this is, inside your jar you have only your classes without any dependencies. To include all the dependencies inside your jar you need to create a fat jar.

Replace your build block with following inside pom.xml:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <!-- get all project dependencies -->
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <!-- MainClass in mainfest make a executable jar -->
                    <archive>
                        <manifest>
                            <mainClass>App</mainClass>
                        </manifest>
                    </archive>

                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <!-- bind to the packaging phase -->
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

After running mvn clean package you will get two jar inside your target directory, first one is without dependency and the second one is with dependencies. Run the second jar.

  1. CustomerJdbc-0.0.1-SNAPSHOT.jar
  2. CustomerJdbc-0.0.1-SNAPSHOT-jar-with-dependencies.jar
Monzurul Shimul
  • 8,132
  • 2
  • 28
  • 42
1

The reason that you're getting that is because the maven-jar-plugin doesn't actually include any of the JARs that are referenced in the POM file by default.

There are a few ways that you can sort this out, this answer seems pretty comprehensive.

Also note that when referencing the main class in the POM, you need to reference it with the fully qualified class name (net.ubilife.spring.customerjdbc.App).

Community
  • 1
  • 1
jas_raj
  • 1,131
  • 6
  • 14
  • Thanks for your reply! But the App is at the root folder. I have just upload the folder structure in my question. – Spider Feb 07 '17 at 16:47
0

You can also run it with Shade to build the jar with the dependencies.

Just add "shade:shade" to the goals.

Example: mvn clean install shade:shade