javagwtspring-bootvaadin7vaadin4spring

Getting null pointer when using autowire for EventBus.UIEvent in vaadin application using springboot


I am using vaadin springboot and I getting null pointer when using autowire for EventBus.UIEventBus.

I already have vaadinsessionscope bean in application of springboot. And I also able to create a EventBus.UIEventBus eventBus in main UI class.

What I am trying to do in below code is pass the event from loginview to my main vaadin UI class. And get a null pointer for EventBus.UIEventBus eventBus which is auto wired.

Any input are appreciated . Thank you.

    <?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>org.pk.connect2x</groupId>
    <artifactId>connect2x</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>connect2x</name>
    <description>get data from any source to any destination.</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
            <version>1.0.0.beta3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <version>1.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.vaadin.spring</groupId>
            <artifactId>spring-vaadin-eventbus</artifactId>
            <version>0.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.atmosphere</groupId>
            <artifactId>atmosphere-runtime</artifactId>
            <version>2.4.0-RC1</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>7.4.5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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


</project>

Below is springboot application class

    package connect2x;

import com.vaadin.spring.internal.VaadinSessionScope;
import org.atmosphere.cpr.SessionSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.annotation.EnableVaadinEventBus;
import org.vaadin.spring.events.support.ApplicationContextEventBroker;

@SpringBootApplication
@EnableVaadinEventBus
public class Connect2xApplication {

    @Autowired
    EventBus.ApplicationEventBus applicationEventBus;


    @Bean
    ApplicationContextEventBroker applicationContextEventBroker() {
        return new ApplicationContextEventBroker(applicationEventBus);
    }

    @Bean
    public SessionSupport atmosphereSessionSupport() {
        return new SessionSupport();
    }

    @Bean
    static VaadinSessionScope vaadinSessionScope() {
        return new VaadinSessionScope();
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        return factory;
    }

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

Below is Main UI class, were there is no null pointer for eventbus

package connect2x;

import com.vaadin.annotations.Theme;
import com.vaadin.server.Responsive;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
import connect2x.com.pk.connect2x.view.Login;
import connect2x.com.pk.connect2x.view.MainView;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusListener;

import java.util.Locale;

/**
 * Created by karthikmarupeddi on 7/18/15.
 */
@SpringUI
@Theme("valo")
public class Connect2xUI extends UI implements EventBusListener<Object> {


    @Autowired
    EventBus.UIEventBus eventBus;

    @Autowired
    Login login;

    @Override
    protected void init(VaadinRequest vaadinRequest) {

        setLocale(Locale.US);

        Responsive.makeResponsive(this);
        addStyleName(ValoTheme.UI_WITH_MENU);

        updateContent();

    }

    /**
     * Updates the correct content for this UI based on the current user status.
     * If the user is logged in with appropriate privileges, main view is shown.
     * Otherwise login view is shown.
     */
    private void updateContent() {
//        User user = (User) VaadinSession.getCurrent().getAttribute(
//                User.class.getName());
//        if (user != null && "admin".equals(user.getRole())) {
//            // Authenticated user
//            setContent(new MainView());
//            removeStyleName("loginview");
//            getNavigator().navigateTo(getNavigator().getState());
//        } else {
//            //setContent(loginView);
//            setContent(new MainView());
//            addStyleName("loginview");
//        }
        setContent(login);
        addStyleName("loginview");
    }




    /**
     * Called when an event has been received.
     *
     * @param event the event, never {@code null}.
     */
    @Override
    public void onEvent(org.vaadin.spring.events.Event<Object> event) {

        System.out.println("****************printing data***************" );
        setContent(new MainView());
        removeStyleName("loginview");
        getNavigator().navigateTo(getNavigator().getState());


    }
}

Login is the java class where I am getting a null pointer for eventbus

    package connect2x.com.pk.connect2x.view;

import com.vaadin.event.ShortcutAction;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.Responsive;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.ValoTheme;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusListener;

/**
 * Created by karthikmarupeddi on 7/18/15.
 */
@UIScope
@SpringComponent
public class Login extends VerticalLayout implements EventBusListener<Object> {


    @Autowired
    EventBus.UIEventBus eventBus;


    public Login() {
        eventBus.subscribe(this);
        setSizeFull();

        Component loginForm = buildLoginForm();
        addComponent(loginForm);
        setComponentAlignment(loginForm, Alignment.MIDDLE_CENTER);
    }


    private Component buildLoginForm() {
        final VerticalLayout loginPanel = new VerticalLayout();
        loginPanel.setSizeUndefined();
        loginPanel.setSpacing(true);
        Responsive.makeResponsive(loginPanel);
        loginPanel.addStyleName("login-panel");

        loginPanel.addComponent(buildLabels());
        loginPanel.addComponent(buildFields());
        loginPanel.addComponent(new CheckBox("Remember me", true));
        return loginPanel;
    }


    private Component buildLabels() {
        CssLayout labels = new CssLayout();
        labels.addStyleName("labels");

        Label welcome = new Label("Welcome");
        welcome.setSizeUndefined();
        welcome.addStyleName(ValoTheme.LABEL_H4);
        welcome.addStyleName(ValoTheme.LABEL_COLORED);
        labels.addComponent(welcome);

        Label title = new Label("Connect2X");
        title.setSizeUndefined();
        title.addStyleName(ValoTheme.LABEL_H3);
        title.addStyleName(ValoTheme.LABEL_LIGHT);
        labels.addComponent(title);
        return labels;
    }


    private Component buildFields() {
        HorizontalLayout fields = new HorizontalLayout();
        fields.setSpacing(true);
        fields.addStyleName("fields");

        final TextField username = new TextField("Username");
        username.setIcon(FontAwesome.USER);
        username.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON);

        final PasswordField password = new PasswordField("Password");
        password.setIcon(FontAwesome.LOCK);
        password.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON);

        final Button signin = new Button("Sign In");
        signin.addStyleName(ValoTheme.BUTTON_PRIMARY);
        signin.setClickShortcut(ShortcutAction.KeyCode.ENTER);
        signin.focus();

        fields.addComponents(username, password, signin);
        fields.setComponentAlignment(signin, Alignment.BOTTOM_LEFT);

        signin.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(final Button.ClickEvent event) {
                System.out.println("*************click listener **************");
                eventBus.publish(Login.this, "Hello World from UI");
                removeStyleName("loginview");

            }
        });

        return fields;

    }

    /**
     * Called when an event has been received.
     *
     * @param event the event, never {@code null}.
     */
    @Override
    public void onEvent(org.vaadin.spring.events.Event<Object> event) {
        System.out.println("*************click listener **************");
    }
}

Solution

  • I think you should be implementing InitializingBean interface and override the afterPropertiesSet method to subscribe the eventBus.

    @Override
    public void afterPropertiesSet() throws Exception {     
    this.eventBus.subscribe(this);
    }
    

    Please check out this code too: https://github.com/joshlong/vaadin-and-spring-talk/