hancock46
hancock46

Reputation: 51

Spring autowiring not working in Vaadin 7 UI

I have a Vaadin 7 project. It's works. Now I need to implement Hibernate 4 to access Database and I want to use also Spring 4 to use its annotations.

The problem is that the autowired annotation doesn't work. The related object is always null.

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

    <groupId>bermacorp</groupId>
    <artifactId>b-sci</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>b-sci</name>

    <properties>
        <vaadin.version>7.6.1</vaadin.version>
        <vaadin.plugin.version>${vaadin.version}</vaadin.plugin.version>
        <jetty.plugin.version>9.2.3.v20140905</jetty.plugin.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <spring.version>4.2.3.RELEASE</spring.version>
        <version.hibernate>4.3.6.Final</version.hibernate>
        <version.slf4j>1.5.8</version.slf4j>
    </properties>

    <repositories>
        <repository>
            <id>vaadin-addons</id>
            <url>http://maven.vaadin.com/vaadin-addons</url>
        </repository>
        <repository>
            <id>vaadin-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

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

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-push</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-client</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-client-compiler</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-themes</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${version.hibernate}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.0.2.GA</version>
        </dependency>

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

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>8.4-702.jdbc4</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <packagingExcludes>WEB-INF/classes/VAADIN/gwt-unitCache/**,
                        WEB-INF/classes/VAADIN/widgetsets/WEB-INF/**</packagingExcludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.plugin.version}</version>
                <configuration>
                    <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
                    <webappDirectory>${basedir}/target/classes/VAADIN/widgetsets</webappDirectory>
                    <draftCompile>false</draftCompile>
                    <compileReport>false</compileReport>
                    <style>OBF</style>
                    <strict>true</strict>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>update-theme</goal>
                            <goal>update-widgetset</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.6.1</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>src/main/webapp/VAADIN/themes</directory>
                            <includes>
                                <include>**/styles.css</include>
                                <include>**/styles.scss.cache</include>
                            </includes>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>${jetty.plugin.version}</version>
                <configuration>
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                </configuration>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>com.vaadin</groupId>
                                        <artifactId>
                                            vaadin-maven-plugin
                                        </artifactId>
                                        <versionRange>[7.1.11,)</versionRange>
                                        <goals>
                                            <goal>resources</goal>
                                            <goal>update-widgetset</goal>
                                            <goal>compile</goal>
                                            <goal>compile-theme</goal>
                                            <goal>update-theme</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

    </build>

    <profiles>
        <profile>
            <id>vaadin-prerelease</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>

            <repositories>
                <repository>
                    <id>vaadin-prereleases</id>
                    <url>http://maven.vaadin.com/vaadin-prereleases</url>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>vaadin-prereleases</id>
                    <url>http://maven.vaadin.com/vaadin-prereleases</url>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>

</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>b-sci</display-name>

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

  <servlet>
        <servlet-name>Bsci</servlet-name>
        <servlet-class>bsci.BsciServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>bsci.BsciUI</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Bsci</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

    <context:property-placeholder location = "classpath:application.properties"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>bsci.entity</value>
            </list>
        </property>

    </bean>

   <bean id="transactionManager"  class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <context:annotation-config />
    <tx:annotation-driven/>

   <context:component-scan base-package="bsci.dao"/>

   <bean class="bsci.service.impl.ServizioImpl" id="servizio"/>
</beans>

BsciServlet.java

package bsci;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.vaadin.server.ServiceException;
import com.vaadin.server.SessionInitEvent;
import com.vaadin.server.SessionInitListener;
import com.vaadin.server.VaadinServlet;

@SuppressWarnings("serial")
public class BsciServlet extends VaadinServlet implements SessionInitListener {

    private WebApplicationContext webApplicationContext;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        try {
            this.webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
        } catch (IllegalStateException e) {
            throw new ServletException("could not locate containing WebApplicationContext");
        }

        AutowireCapableBeanFactory ctx = getWebApplicationContext().getAutowireCapableBeanFactory();

        ctx.autowireBean(this);
    }

    protected final AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws ServletException {
        try {
            return getWebApplicationContext().getAutowireCapableBeanFactory();
        } catch (IllegalStateException e) {
            throw new ServletException("containing context " + getWebApplicationContext() + " is not autowire-capable", e);
        }
    }

    protected final WebApplicationContext getWebApplicationContext() throws ServletException {
        if (this.webApplicationContext == null) {
            throw new ServletException("can't retrieve WebApplicationContext before init() is invoked");
        }
        return this.webApplicationContext;
    }

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
    }

    @Override
    protected final void servletInitialized() throws ServletException {
        super.servletInitialized();
        getService().addSessionInitListener(this);
        getService().addSessionInitListener(new BsciSessionInitListener());
    }
}

BsciSessionInitListener.java

package bsci;

import org.jsoup.nodes.Element;

import com.vaadin.server.BootstrapFragmentResponse;
import com.vaadin.server.BootstrapListener;
import com.vaadin.server.BootstrapPageResponse;
import com.vaadin.server.ServiceException;
import com.vaadin.server.SessionInitEvent;
import com.vaadin.server.SessionInitListener;

@SuppressWarnings("serial")
public class BsciSessionInitListener implements SessionInitListener {

    @Override
    public final void sessionInit(final SessionInitEvent event)
            throws ServiceException {

        event.getSession().addBootstrapListener(new BootstrapListener() {

            @Override
            public void modifyBootstrapPage(final BootstrapPageResponse response) {
                final Element head = response.getDocument().head();
                head.appendElement("meta")
                        .attr("name", "viewport")
                        .attr("content",
                                "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no");
                head.appendElement("meta")
                        .attr("name", "apple-mobile-web-app-capable")
                        .attr("content", "yes");
                head.appendElement("meta")
                        .attr("name", "apple-mobile-web-app-status-bar-style")
                        .attr("content", "black-translucent");

                String contextPath = response.getRequest().getContextPath();
            }

            @Override
            public void modifyBootstrapFragment(
                    final BootstrapFragmentResponse response) {
            }
        });
    }

}

Now in my UI class the autowired object is always null.

package bsci;

import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.eventbus.Subscribe;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent;
import com.vaadin.server.Page.BrowserWindowResizeListener;
import com.vaadin.server.Responsive;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.ValoTheme;

import bsci.data.DataProvider;
import bsci.data.DummyDataProvider;
import bsci.entity.Utente;
import bsci.event.BsciEvent.BrowserResizeEvent;
import bsci.event.BsciEvent.CloseOpenWindowsEvent;
import bsci.event.BsciEvent.UserLoggedOutEvent;
import bsci.event.BsciEvent.UserLoginRequestedEvent;
import bsci.event.BsciEventBus;
import bsci.service.Servizio;
import bsci.view.LoginView;
import bsci.view.MainView;

@Theme("bscitheme")
@Widgetset("bsci.BsciWidgetset")
public final class BsciUI extends UI {

    @Autowired
    Servizio servizio;

    private final DataProvider dataProvider = new DummyDataProvider();
    private final BsciEventBus dashboardEventbus = new BsciEventBus();

    @Override
    protected void init(final VaadinRequest request) {

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

        updateContent();

        Page.getCurrent().addBrowserWindowResizeListener(new BrowserWindowResizeListener() {
            @Override
            public void browserWindowResized(final BrowserWindowResizeEvent event) {
                BsciEventBus.post(new BrowserResizeEvent());
            }
        });
    }

    private void updateContent() {
        Utente user = (Utente) VaadinSession.getCurrent().getAttribute(Utente.class.getName());
        if (user != null) {
            setContent(new MainView());
            removeStyleName("loginview");
            getNavigator().navigateTo(getNavigator().getState());
        } else {
            setContent(new LoginView());
            addStyleName("loginview");
        }
    }

    @Subscribe
    public void userLoginRequested(final UserLoginRequestedEvent event) {
        Utente user = getDataProvider().authenticate(event.getUserName(), event.getPassword());
        VaadinSession.getCurrent().setAttribute(Utente.class.getName(), user);
        updateContent();
    }

    @Subscribe
    public void userLoggedOut(final UserLoggedOutEvent event) {
        VaadinSession.getCurrent().close();
        Page.getCurrent().reload();
    }

    @Subscribe
    public void closeOpenWindows(final CloseOpenWindowsEvent event) {
        for (Window window : getWindows()) {
            window.close();
        }
    }

    public static DataProvider getDataProvider() {
        return ((BsciUI) getCurrent()).dataProvider;
    }

    public static BsciEventBus getDashboardEventbus() {
        return ((BsciUI) getCurrent()).dashboardEventbus;
    }

    public Servizio getServizio() {
        return servizio;
    }
}

Can you help me, please? I don't understand the reason.

Upvotes: 0

Views: 1718

Answers (2)

hancock46
hancock46

Reputation: 51

Thanks all, but I solved the problem using vaadin spring integration add-on

<dependency>
    <groupId>ru.xpoft.vaadin</groupId>
    <artifactId>spring-vaadin-integration</artifactId>
    <version>3.2</version>
</dependency>

Upvotes: 0

herman
herman

Reputation: 12305

The reason is that you're trying to let Spring inject something into your UI, but Spring doesn't know about your UI.

Use the Vaadin Spring integration instead of implementing it yourself. Doing it yourself is possible, but then you need some place where you manually look up some Components in the WebApplicationContext, for example the View components could be prototype scoped beans looked up in a ViewProvider used by the Navigator. But now that we have the official Vaadin Spring integration this isn't necessary anymore.

Upvotes: 1

Related Questions