Sophie E
Sophie E

Reputation: 67

No qualifying bean - FxWeaver and Spring Boot

I am trying to refactor a Java program I wrote last year to use Spring Boot. The front end uses JavaFX, and so I am trying to use FxWeaver.

However, when I run my program, I get the following error on startup:

Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.rgielen.fxweaver.core.FxWeaver' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    ...

From rgielen's website, it shouldn't be necessary to provide an RxWeaver "... when using the Spring Boot Starter, since it provides auto-configuration for a FxWeaver instance."

So I'm stumped as to why I'm getting this error. Would anyone be able to take a look please?

Main Application

package application;


import org.springframework.boot.autoconfigure.SpringBootApplication;
import javafx.application.Application;


@SpringBootApplication
public class MainApplication  {

    public static void main(String[] args) {

        Application.launch(SpringbootJavaFxApplication.class, args); 
    }

}

SpringBootJavaFxApplication

package application;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import net.rgielen.fxweaver.core.FxWeaver;


public class SpringbootJavaFxApplication extends Application {

    private ConfigurableApplicationContext applicationContext;

    @Override
    public void init() throws Exception {
        this.applicationContext = new SpringApplicationBuilder() 
                .sources(MainApplication.class)
                .run(getParameters().getRaw().toArray(new String[0]));
    }


    @Override
    public void start(Stage stage) {
        FxWeaver fxWeaver = applicationContext.getBean(FxWeaver.class);
        Parent root = fxWeaver.loadView(Controller.class);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }


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

}

pom

<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>xxxxx</groupId>
    <artifactId>xxxxx</artifactId>
    <version>1.0</version>
    <name>xxxxx</name>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

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

    <dependencies>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.10.19</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>12.0.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

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

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

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

        <dependency>
            <groupId>net.rgielen</groupId>
            <artifactId>javafx-weaver-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <mainClass>application.Main</mainClass>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(Obviously the pom contains things not specifically related to this issue, but I'm including the whole file in case anything else present is causing this issue.)

Please can you let me know if you have worked out what is causing the problem? I'm tearing my hair out with this now!

Also, apologies if I've not included the right/sufficient information. This is my first post on here. I am using eclipse.

Thank you!

Upvotes: 2

Views: 1787

Answers (4)

Malavan
Malavan

Reputation: 41

If anyone looking for this: Defining a Been in the SpringBootApplication does the trick.

@Bean
    public FxWeaver fxWeaver(ConfigurableApplicationContext applicationContext) {
        // Would also work with javafx-weaver-core only:
        // return new FxWeaver(applicationContext::getBean, applicationContext::close);
        return new SpringFxWeaver(applicationContext); 
    }

Upvotes: 1

GrolarDan
GrolarDan

Reputation: 151

I had the same problem. I checked Spring conditions evaluation report and found this:

FxWeaverAutoConfiguration:
Did not match: - @ConditionalOnClass did not find required class 'javafx.fxml.FXMLLoader' (OnClassCondition)

So I put dependency on javafx-fxml

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>12.0.2</version>
</dependency>

And the condition was satisfied.
This worked for me.

Upvotes: 0

rgielen
rgielen

Reputation: 186

Maybe I'm too late to help, but:

I re-created an example based on a minimal pom and your Java code. I could not re-produce your issue, though.

Here is my pom:

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.rgielen.sample</groupId>
    <artifactId>fxweaver-springboot-starter-sample</artifactId>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>net.rgielen</groupId>
            <artifactId>javafx-weaver-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

What concerns me with your pom

  1. it adds a dependency on OpenJFX 12 (targeted at JDK 12), but compiles with target 1.8 - which in a Spring Boot application would be easier to define with the java.version property. When using a 1.8 JRE with embedded JavaFX (Oracle, Liberica) you would not need OpenJFX deps at all
  2. You don't need javafx-maven-plugin when packaging as Spring Boot application.

That said, I fail to see this as root cause.

If you want to compare in detail, here's the code: https://github.com/rgielen/fxweaver-springboot-stripped-demo

Upvotes: 2

Sophie E
Sophie E

Reputation: 67

Just a brief update for anybody who finds this in future. I was unable to resolve the problem in the end, so instead went for a full refactor of the code, without the use of FxWeaver.

More labour-intensive, but the resulting code is arguably much better as a result.

Upvotes: 0

Related Questions