Run spring boot with jdk9 using jigsaw modules
Asked Answered
I

4

7

What's wrong with this application. I thought the mix of classpath jars and module jars are valid. For all jars not having an explicit module-info become an automatic module? When I delete my module-info.java it works. Because IDEA using the classpath for this case.

Java(TM) SE Runtime Environment (build 9+176)

IntelliJ IDEA 2017.1.4

module-info.java

module test {
    requires spring.boot.autoconfigure;
    requires spring.boot;
}

App.java

package com.foo.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

pom.xml

<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.foo.test</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.M2</version>
    </parent>

    <name>test</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.9</maven.compiler.source>
        <maven.compiler.target>1.9</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationContextInitializer : org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer at [email protected]/org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:439) at [email protected]/org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:418) at [email protected]/org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:409) at [email protected]/org.springframework.boot.SpringApplication.(SpringApplication.java:266) at [email protected]/org.springframework.boot.SpringApplication.(SpringApplication.java:247) at [email protected]/org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) at [email protected]/org.springframework.boot.SpringApplication.run(SpringApplication.java:1233) at test/com.foo.test.App.main(App.java:10) Caused by: java.lang.NoClassDefFoundError: java/sql/SQLException at [email protected]/org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:145) at [email protected]/org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:435) ... 7 more Caused by: java.lang.ClassNotFoundException: java.sql.SQLException at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) ... 9 more

Istria answered 4/7, 2017 at 16:37 Comment(1)
It is highly recommended to name your module according to your package. For example module com.foo.test {...}Meghanmeghann
M
7

I assume spring.boot is an automatic module. An automatic module doesn't declare it dependences so you have to use --add-modules to ensure that any explicit modules needed are resolved. If spring.boot were an explicit module then I assume it would requires java.sql and you won't have this issue.

Mintun answered 5/7, 2017 at 11:33 Comment(3)
vm argument: --add-modules=java.sql also works but that is not would you mean?Istria
Yes, I meant --add-modules=java.sql to ensure that the java.sql module is resolved. It will not otherwise be resolved because no module requires it. You have worked around it by adding requires java.sql to your module but that should not be needed (and won't be needed once spring.boot is migrated to an explicit module).Mintun
Alex Buckley told us at devoxxUS (Modular Development with JDK 9) automatic modules: "... Requires everything, they require each other, they require all modules in the jdk image and they require all of your modules as well, and they export their packages..." (The quote is similar what he said). I still don't get it why I have to add the java.sql module. And anyway when it's necessary why only java.sql? I'm pretty sure spring.boot has some more. Is requires and "declare dependences" not the same?Istria
I
5

finally, I got it... my module-info have to look like this:

module test {
    requires java.sql; // my real problem solved with this
    requires spring.boot.autoconfigure;
    requires spring.boot;
    exports com.foo.test; // subsequent error 1: beeing accessible for some spring modules
    opens com.foo.test to spring.core; // subsequent error 2: beeing accessible for spring.core in a deep reflection way
}

Can someone explain why I have to requires java.sql; inside my own module when I don't use it?

Istria answered 5/7, 2017 at 8:47 Comment(1)
because java.sql is required by spring. Since spring is automatic module it does not declare what it needs to work, so you need to include java.sql to the module graph either by --add-modules java.sql or by requires java.sql in your own modulePurvis
R
1

I had the same issue when upgraded from Java 8 to Java 11.

Solved by selecting different option in Intellij run configuration: shorten command line

Ragnar answered 1/9, 2020 at 11:43 Comment(0)
I
-2

This is almost certainly because you are missing the jdbc driver jar for MySql. you need to use this dependency :-

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>6.0.5</version>
</dependency>
Injunction answered 4/7, 2017 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.