tako21osan
tako21osan

Reputation: 11

A NamingException occurs when running a Spring project packaged as an executable (exe)

I am developing a desktop application that combines Spring and OpenJFX, but I am facing an issue where the executable created by jpackage is not functioning correctly. Upon checking the logs, I found that a javax/naming/NamingException error is occurring.


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.4.2)

2025-02-13T21:53:15.250+09:00  INFO 9960 --- [JavaFX-Launcher] o.s.boot.SpringApplication               : Starting application using Java 22.0.1 with PID 9960 (started by tako21osan in C:\Users\tako21osan\Desktop\250205\myapp\myapp\myapp\MyApp)
2025-02-13T21:53:15.253+09:00  INFO 9960 --- [JavaFX-Launcher] o.s.boot.SpringApplication               : No active profile set, falling back to 1 default profile: "default"
2025-02-13T21:53:15.694+09:00  WARN 9960 --- [JavaFX-Launcher] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [test.myapp.MyApp]: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$PooledDataSourceConfiguration due to javax/naming/NamingException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
2025-02-13T21:53:15.703+09:00  INFO 9960 --- [JavaFX-Launcher] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-02-13T21:53:15.720+09:00 ERROR 9960 --- [JavaFX-Launcher] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [test.myapp.MyApp]: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$PooledDataSourceConfiguration due to javax/naming/NamingException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
    at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:613) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:836) ~[spring-context-6.2.2.jar:6.2.2]
    at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:833) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:803) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:418) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149) ~[spring-boot-3.4.2.jar:3.4.2]
    at test.myapp.MyApp.init(MyApp.java:22) ~[myapp-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
    at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:817) ~[javafx.graphics:na]
    at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196) ~[javafx.graphics:na]
    at java.base/java.lang.Thread.run(Thread.java:1570) ~[na:na]
Caused by: java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$PooledDataSourceConfiguration due to javax/naming/NamingException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:54) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:99) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:233) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:413) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:294) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:267) ~[spring-context-6.2.2.jar:6.2.2]
    at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:603) ~[spring-context-6.2.2.jar:6.2.2]
    ... 19 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/naming/NamingException
    at org.springframework.boot.jdbc.DataSourceBuilder$HikariDataSourceProperties.<init>(DataSourceBuilder.java:611) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.jdbc.DataSourceBuilder$MappedDataSourceProperties.lookup(DataSourceBuilder.java:439) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.jdbc.DataSourceBuilder$MappedDataSourceProperties.lookupPooled(DataSourceBuilder.java:405) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.jdbc.DataSourceBuilder$MappedDataSourceProperties.forType(DataSourceBuilder.java:395) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.jdbc.DataSourceBuilder.findType(DataSourceBuilder.java:267) ~[spring-boot-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$PooledDataSourceAvailableCondition.getMatchOutcome(DataSourceAutoConfiguration.java:118) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberOutcomes.getConditionOutcome(AbstractNestedCondition.java:195) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberOutcomes.<init>(AbstractNestedCondition.java:189) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.lambda$getMatchOutcomes$0(AbstractNestedCondition.java:169) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986) ~[na:na]
    at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179) ~[spring-core-6.2.2.jar:6.2.2]
    at java.base/java.util.Collections$UnmodifiableMap.forEach(Collections.java:1708) ~[na:na]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.getMatchOutcomes(AbstractNestedCondition.java:169) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberMatchOutcomes.<init>(AbstractNestedCondition.java:78) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition.getMatchOutcome(AbstractNestedCondition.java:63) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.4.2.jar:3.4.2]
    ... 25 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.naming.NamingException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[na:na]
    ... 41 common frames omitted

The same exception occurred even when I created a minimal project to isolate the cause. If you have any information or solutions regarding similar NamingException issues, I would appreciate it if you could let me know.

Currently, the application generates the GUI using FXML and handles the database connection. In the future, I am considering introducing Tomcat and combining it with OpenJFX WebView.

jpackage Command

jpackage --type app-image --win-console --input ".\target" --name MyApp --main-class "test.myapp.MyApp" --main-jar "myapp-1.0-SNAPSHOT.jar" --runtime-image ".\target\jre_set" --dest ".\"

application.yml

spring:
  datasource:
    url: 'jdbc:sqlite:file::memory:?cache=shared'
    driver-class-name: org.sqlite.JDBC
  jpa:
    show-sql: true
    properties:
      hibernate:
        dialect: 'org.hibernate.community.dialect.SQLiteDialect'

logging:
  level:
    org.hibernate.SQL: DEBUG
    #org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    #org.springframework.boot.autoconfigure: DEBUG

MyApp.class

@SpringBootApplication
public class MyApp extends Application {

    private ConfigurableApplicationContext appContext;
    private Parent root;

    @Override
    public void init() throws Exception{
        appContext = new SpringApplicationBuilder(MyApp.class)
                .run(getParameters().getRaw().toArray(new String[0]));

        FXMLLoader loader = new FXMLLoader(MyApp.class.getResource("hello-view.fxml"));
        root = loader.load();
    }

    @Override
    public void start(Stage stage) {
        stage.setTitle("MyAppView");

        Scene scene = new Scene(root, 480, 320);
        stage.setScene(scene);
        stage.show();
    }

    @Override
    public void stop(){
        appContext.close();
        Platform.exit();
    }

    public static void main(String... args){
        Application.launch(MyApp.class, args);
    }

}

MyAppDataBaseConfig.class

@Configuration(proxyBeanMethods = false)
public class MyAppDataBaseConfig {

    final DataSourceProperties DATA_SOURCE_PROPERTY;

    @Autowired
    public MyAppDataBaseConfig(DataSourceProperties dataSource){
        this.DATA_SOURCE_PROPERTY = dataSource;
    }

    @Bean
    @Primary
    public DataSource backDataSource() {
        SQLiteDataSource sqlDs = new SQLiteDataSource();
        sqlDs.setUrl(DATA_SOURCE_PROPERTY.getUrl());
        return sqlDs;
    }
}

pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>test</groupId>
    <artifactId>myapp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>myapp</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>21</java.version>
        <jfx.version>21.0.1</jfx.version>
        <slf4j.version>2.0.16</slf4j.version>
    </properties>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-community-dialects</artifactId>
            <version>6.6.1.Final</version>
        </dependency>

        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.46.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${jfx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${jfx.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-reload4j</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <excludeGroupIds>org.openjfx</excludeGroupIds>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>

Upvotes: -1

Views: 95

Answers (1)

tako21osan
tako21osan

Reputation: 11

The problem was caused by a lack of modules to include in the custom Jre.

I am still not understanding the relationship between java.naming and javax.naming, but based on life8888888's advice, I re-created the custom JRE to include java.naming and it now starts correctly. I still lack the knowledge to determine which modules are needed, but I will close this trouble for the time being. Thanks to all of you for your advice.

Upvotes: 0

Related Questions