Миграция веб-приложения на Spring 4 с JDK8 и лямбдами

в 22:38, , рубрики: java, jdk8, lambda, spring framework, метки: , , ,

Данная статься будет интересна тем, кто желает проапгрейдиться на Spring 4.0 M1 и побаловаться с JDK8(которая в принципе еще далеко до релиза), в которой есть поддержка лямб в своем проекте.
(В более ранних версиях этого было не достичь из-за более ранней версии библиотеки ASM, включенной в spring).

Кого интересует как — прошу под кат.

Жил я спокойно, пока сегодня вечером не наткнулся на запись о том, что доступен Milestone Spring 4.0, в котором добавили поддердку для JDK 8.

Дело за малым — добавляем репозиторий спринга в свой мавен проект:

<repositories>
...
        <repository>
            <id>spring-milestone</id>
            <name>Spring Source Milestone Repository</name>
            <url>http://repo.springsource.org/milestone/</url>
        </repository>
...
 </repositories>

и меняем версии зависимостей spring'a на «4.0.0.M1».

И естественно приложение перестало запускаться после апгрейда :)
На сей раз по причине того, что не найдены xsd файлы.

У меня типично присутствует вот такого типа шапка в XML конфигурации Spring'a в моих (веб-)приложениях:

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
...

Замена «3.2» в этой XML-шапке на «4.0» не привела ни к чему, ибо xsd в паблике еще не лежат, так как это все еще milestone.

Дальше оказалось несколько вариантов развития событий:
1). Полностью отказаться от XML конфигураций и перейти на программатическую конфигурацию(тык).
2). Забыть и забить о spring framework 4.0 пока «все само не пофиксится» со временем.
3). Вспомнить о том, что «я и сам милиционер» и взяться за дебагер.

Я выбрал 3-ий вариант.

Через несколько минут дебугирования выяснилось, что Spring позволяет отключить валидацию схемы.

В случае моего веб-приложения я лишь немножко подправил web.xml и добваил один класс.
web.xml до:

...
    <servlet>
        <servlet-name>spring-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring-dispatcher-servlet.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
...

после:

...
    <servlet>
        <servlet-name>spring-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring-dispatcher-servlet.xml
            </param-value>
        </init-param>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>springutils.XmlWebApplicationContextWithDisabledValidation</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
...

контент класса «springutils.XmlWebApplicationContextWithDisabledValidation»:

package springutils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.web.context.support.XmlWebApplicationContext;

import java.io.IOException;

public class XmlWebApplicationContextWithDisabledValidation extends XmlWebApplicationContext {
    /**
     * Loads the bean definitions via an XmlBeanDefinitionReader.
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     * @see #initBeanDefinitionReader
     * @see #loadBeanDefinitions
     */
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        //disable validation.
        beanDefinitionReader.setValidating(false);

        // Allow a subclass to provide custom initialization of the reader,
        // then proceed with actually loading the bean definitions.
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }
}

Проект поднялся и отвалился, но уже с другой проблемой: В проекте также присутствует JPA провайдер Hibernate (v 4.2.2.Final), который не смог прочитать класс-файлы с такими вещами(лямбдами) при поиске аннотированных классов. Проблема заключалась в том, что использовался javassist версии 3.15.0-GA. Апгрейд этой зависимости до версии 3.17.1-GA помог мне начать баловаться с JDK 8 в моем проекте.

Проект смигрирован на spring 4 и JDK8 c лямбдами. Профит.

Надеюсь мой опыт поможет кому-то сэкономить нервные клетки.

P.S. Извиняюсь за некоторый сумбур в изложении.

Автор: skywatcher

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js