From e4173189150fe1070692a228e3b6d6b377b303d3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 6 Oct 2020 15:31:19 +0200 Subject: [PATCH 1/4] Revise native Hibernate 5 bootstrapping with JTA transaction manager Closes gh-25858 --- .../LocalSessionFactoryBuilder.java | 2 + src/docs/asciidoc/data-access.adoc | 136 ++++++++++++------ 2 files changed, 91 insertions(+), 47 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index e6f50a90d62..493743d1727 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -225,6 +225,8 @@ public class LocalSessionFactoryBuilder extends Configuration { "Unknown transaction manager type: " + jtaTransactionManager.getClass().getName()); } + getProperties().put(AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY, "jta"); + // Hibernate 5.1/5.2: manually enforce connection release mode AFTER_STATEMENT (the JTA default) try { // Try Hibernate 5.2 diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc index ce97661743d..bf27fbf13d1 100644 --- a/src/docs/asciidoc/data-access.adoc +++ b/src/docs/asciidoc/data-access.adoc @@ -381,6 +381,19 @@ NOTE: The preceding definition of the `dataSource` bean uses the ` from the `jee` namespace. For more information see <>. +NOTE: If you use JTA, your transaction manager definition should look the same, regardless +of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported +technology. This is due to the fact that JTA transactions are global transactions, which +can enlist any transactional resource. + +In all Spring transaction setups, application code does not need to change. You can change +how transactions are managed merely by changing configuration, even if that change means +moving from local to global transactions or vice versa. + + +[[transaction-strategies-hibernate]] +==== Hibernate Transaction Setup + You can also easily use Hibernate local transactions, as shown in the following examples. In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your application code can use to obtain Hibernate `Session` instances. @@ -420,21 +433,52 @@ example declares `sessionFactory` and `txManager` beans: If you use Hibernate and Java EE container-managed JTA transactions, you should use the same `JtaTransactionManager` as in the previous JTA example for JDBC, as the following -example shows: +example shows. Also, it is recommended to make Hibernate aware of JTA through its +transaction coordinator and possibly also its connection release mode configuration: [source,xml,indent=0,subs="verbatim,quotes"] ---- + + + + + org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml + + + + + hibernate.dialect=${hibernate.dialect} + hibernate.transaction.coordinator_class=jta + hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT + + + + ---- -NOTE: If you use JTA, your transaction manager definition should look the same, regardless -of what data access technology you use, be it JDBC, Hibernate JPA, or any other supported -technology. This is due to the fact that JTA transactions are global transactions, which -can enlist any transactional resource. +Or alternatively, you may pass the `JtaTransactionManager` into your `LocalSessionFactoryBean` +for enforcing the same defaults: -In all these cases, application code does not need to change. You can change how -transactions are managed merely by changing configuration, even if that change means -moving from local to global transactions or vice versa. +[source,xml,indent=0,subs="verbatim,quotes"] +---- + + + + + org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml + + + + + hibernate.dialect=${hibernate.dialect} + + + + + + +---- @@ -3115,8 +3159,8 @@ hierarchy defined in the `org.springframework.dao` package. (See <`) and feed it, for example, to - Spring's `JtaTransactionManager`, the easiest way is to specify a reference to - the bean that defines this JTA `PlatformTransactionManager` instance as the value of the - `jtaTransactionManager` property for `LocalSessionFactoryBean.` Spring then makes the - object available to Hibernate. -* More likely, you do not already have the JTA `PlatformTransactionManager` instance, - because Spring's `JtaTransactionManager` can find it itself. Thus, you need to - configure Hibernate to look up JTA `PlatformTransactionManager` directly. You do this - by configuring an application server-specific `TransactionManagerLookup` class in the - Hibernate configuration, as described in the Hibernate manual. +You can resolve such issues by making Hibernate aware of the JTA transaction manager, +to which it synchronizes (along with Spring). You have two options for doing this: + +* Pass your Spring `JtaTransactionManager` bean to your Hibernate setup. The easiest + way is a bean reference into the `jtaTransactionManager` property for your + `LocalSessionFactoryBean` bean (see <>). + Spring then makes the corresponding JTA strategies available to Hibernate. +* You may also configure Hibernate's JTA-related properties explicitly, in particular + "hibernate.transaction.coordinator_class", "hibernate.connection.handling_mode" + and potentially "hibernate.transaction.jta.platform" in your "hibernateProperties" + on `LocalSessionFactoryBean` (see Hibernate's manual for details on those properties). The remainder of this section describes the sequence of events that occur with and without Hibernate's awareness of the JTA `PlatformTransactionManager`. -When Hibernate is not configured with any awareness of the JTA -`PlatformTransactionManager`, the following events occur when a JTA transaction commits: +When Hibernate is not configured with any awareness of the JTA transaction manager, +the following events occur when a JTA transaction commits: * The JTA transaction commits. * Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so it is @@ -7204,16 +7246,16 @@ When Hibernate is not configured with any awareness of the JTA error, as the application server no longer considers the `Connection` to be usable, because the transaction has already been committed. -When Hibernate is configured with awareness of the JTA `PlatformTransactionManager`, the -following events occur when a JTA transaction commits: +When Hibernate is configured with awareness of the JTA transaction manager, +the following events occur when a JTA transaction commits: * The JTA transaction is ready to commit. * Spring's `JtaTransactionManager` is synchronized to the JTA transaction, so the transaction is called back through a `beforeCompletion` callback by the JTA transaction manager. * Spring is aware that Hibernate itself is synchronized to the JTA transaction and - behaves differently than in the previous scenario. Assuming the Hibernate `Session` - needs to be closed at all, Spring closes it now. + behaves differently than in the previous scenario. In particular, it aligns with + Hibernate's transactional resource management. * The JTA transaction commits. * Hibernate is synchronized to the JTA transaction, so the transaction is called back through an `afterCompletion` callback by the JTA transaction manager and can @@ -7244,13 +7286,13 @@ that is used by the application to obtain an entity manager. [[orm-jpa-setup-lemfb]] ===== Using `LocalEntityManagerFactoryBean` -You can use this option only in simple deployment environments such as stand-alone applications -and integration tests. +You can use this option only in simple deployment environments such as stand-alone +applications and integration tests. The `LocalEntityManagerFactoryBean` creates an `EntityManagerFactory` suitable for -simple deployment environments where the application uses only JPA for data access. The -factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according to -JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the +simple deployment environments where the application uses only JPA for data access. +The factory bean uses the JPA `PersistenceProvider` auto-detection mechanism (according +to JPA's Java SE bootstrapping) and, in most cases, requires you to specify only the persistence unit name. The following XML example configures such a bean: [source,xml,indent=0,subs="verbatim,quotes"] @@ -7734,7 +7776,7 @@ steps: your transaction coordinator. This is usually straightforward in a Java EE environment, exposing a different kind of `DataSource` through JNDI. See your application server documentation for details. Analogously, a standalone transaction coordinator usually -comes with special XA-integrated `DataSource` implementations. Again, check its documentation. +comes with special XA-integrated `DataSource` variants. Again, check its documentation. * The JPA `EntityManagerFactory` setup needs to be configured for JTA. This is provider-specific, typically through special properties to be specified as `jpaProperties` @@ -7743,11 +7785,11 @@ are even version-specific. See your Hibernate documentation for details. * Spring's `HibernateJpaVendorAdapter` enforces certain Spring-oriented defaults, such as the connection release mode, `on-close`, which matches Hibernate's own default in -Hibernate 5.0 but not any more in 5.1/5.2. For a JTA setup, either do not declare -`HibernateJpaVendorAdapter` to begin with or turn off its `prepareConnection` flag. -Alternatively, set Hibernate 5.2's `hibernate.connection.handling_mode` property to +Hibernate 5.0 but not any more in Hibernate 5.1+. For a JTA setup, make sure to declare +your persistence unit transaction type as "JTA". Alternatively, set Hibernate 5.2's +`hibernate.connection.handling_mode` property to `DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT` to restore Hibernate's own default. -See <> for a related note about WebLogic. +See <> for related notes. * Alternatively, consider obtaining the `EntityManagerFactory` from your application server itself (that is, through a JNDI lookup instead of a locally declared From 1745a3f25d0a81d722ee7770006f4269ae5e3094 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 6 Oct 2020 15:31:26 +0200 Subject: [PATCH 2/4] Consistent @Nullable declarations on overridden converter methods --- .../core/convert/support/GenericConversionService.java | 1 + .../core/convert/support/MapToMapConverter.java | 4 ++-- .../core/convert/support/StringToBooleanConverter.java | 2 ++ .../core/convert/support/StringToCharacterConverter.java | 4 +++- .../core/convert/support/StringToEnumConverterFactory.java | 4 +++- .../core/convert/support/StringToNumberConverterFactory.java | 4 +++- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index e8263d9526c..2e966c7a28e 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -687,6 +687,7 @@ public class GenericConversionService implements ConfigurableConversionService { } @Override + @Nullable public Set getConvertibleTypes() { return null; } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java index 9da79dd70b9..5b791f966d6 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,12 +61,12 @@ final class MapToMapConverter implements ConditionalGenericConverter { } @Override - @SuppressWarnings("unchecked") @Nullable public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } + @SuppressWarnings("unchecked") Map sourceMap = (Map) source; // Shortcut if possible... diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToBooleanConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToBooleanConverter.java index a476de69cca..4b1c0fd7b2d 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/StringToBooleanConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToBooleanConverter.java @@ -20,6 +20,7 @@ import java.util.HashSet; import java.util.Set; import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; /** * Converts String to a Boolean. @@ -48,6 +49,7 @@ final class StringToBooleanConverter implements Converter { @Override + @Nullable public Boolean convert(String source) { String value = source.trim(); if (value.isEmpty()) { diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToCharacterConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToCharacterConverter.java index dc4daa9bd42..97374fbba74 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/StringToCharacterConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToCharacterConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.Nullable; /** * Converts a String to a Character. @@ -27,6 +28,7 @@ import org.springframework.core.convert.converter.Converter; final class StringToCharacterConverter implements Converter { @Override + @Nullable public Character convert(String source) { if (source.isEmpty()) { return null; diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java index 6a0c3ba395d..bf4d7fb2c14 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; +import org.springframework.lang.Nullable; /** * Converts from a String to a {@link java.lang.Enum} by calling {@link Enum#valueOf(Class, String)}. @@ -44,6 +45,7 @@ final class StringToEnumConverterFactory implements ConverterFactory Date: Tue, 6 Oct 2020 15:31:34 +0200 Subject: [PATCH 3/4] Polishing --- .../simp/stomp/DefaultStompSession.java | 5 ++- .../support/NativeMessageHeaderAccessor.java | 35 +++++++++++++++---- .../MockHttpServletRequestBuilder.java | 4 +-- .../springframework/http/ResponseCookie.java | 8 ++--- .../reactive/JettyClientHttpRequest.java | 6 +--- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java index 228abd915fb..5e8b5083409 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -272,8 +272,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession { } private boolean isEmpty(@Nullable Object payload) { - return payload == null || StringUtils.isEmpty(payload) || - (payload instanceof byte[] && ((byte[]) payload).length == 0); + return (StringUtils.isEmpty(payload) || (payload instanceof byte[] && ((byte[]) payload).length == 0)); } private void execute(Message message) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java index 5fbb9ead26d..fbd70f3598d 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java @@ -82,7 +82,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { /** - * Sub-classes can use this method to access the "native" headers sub-map. + * Subclasses can use this method to access the "native" headers sub-map. */ @SuppressWarnings("unchecked") @Nullable @@ -139,6 +139,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { /** * Whether the native header map contains the give header name. + * @param headerName the name of the header */ public boolean containsNativeHeader(String headerName) { Map> map = getNativeHeaders(); @@ -146,7 +147,9 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { } /** - * Return the values for the specified native header, if present. + * Return all values for the specified native header, if present. + * @param headerName the name of the header + * @return the associated values, or {@code null} if none */ @Nullable public List getNativeHeader(String headerName) { @@ -156,13 +159,15 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { /** * Return the first value for the specified native header, if present. + * @param headerName the name of the header + * @return the associated value, or {@code null} if none */ @Nullable public String getFirstNativeHeader(String headerName) { Map> map = getNativeHeaders(); if (map != null) { List values = map.get(headerName); - if (values != null) { + if (!CollectionUtils.isEmpty(values)) { return values.get(0); } } @@ -200,6 +205,8 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { * Add the specified native header value to existing values. *

In order for this to work, the accessor must be {@link #isMutable() * mutable}. See {@link MessageHeaderAccessor} for details. + * @param name the name of the header + * @param value the header value to set */ public void addNativeHeader(String name, @Nullable String value) { Assert.state(isMutable(), "Already immutable"); @@ -216,6 +223,10 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { setModified(true); } + /** + * Add the specified native headers to existing values. + * @param headers the headers to set + */ public void addNativeHeaders(@Nullable MultiValueMap headers) { if (headers == null) { return; @@ -227,24 +238,34 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { * Remove the specified native header value replacing existing values. *

In order for this to work, the accessor must be {@link #isMutable() * mutable}. See {@link MessageHeaderAccessor} for details. + * @param headerName the name of the header + * @return the associated values, or {@code null} if the header was not present */ @Nullable - public List removeNativeHeader(String name) { + public List removeNativeHeader(String headerName) { Assert.state(isMutable(), "Already immutable"); Map> nativeHeaders = getNativeHeaders(); - if (nativeHeaders == null) { + if (CollectionUtils.isEmpty(nativeHeaders)) { return null; } - return nativeHeaders.remove(name); + return nativeHeaders.remove(headerName); } + + /** + * Return the first value for the specified native header, + * or {@code null} if none. + * @param headerName the name of the header + * @param headers the headers map to introspect + * @return the associated value, or {@code null} if none + */ @SuppressWarnings("unchecked") @Nullable public static String getFirstNativeHeader(String headerName, Map headers) { Map> map = (Map>) headers.get(NATIVE_HEADERS); if (map != null) { List values = map.get(headerName); - if (values != null) { + if (!CollectionUtils.isEmpty(values)) { return values.get(0); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index 8b844e5b1d3..7a73e731f5e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -700,8 +700,8 @@ public class MockHttpServletRequestBuilder String query = this.url.getRawQuery(); if (!this.queryParams.isEmpty()) { - String s = UriComponentsBuilder.newInstance().queryParams(this.queryParams).build().encode().getQuery(); - query = StringUtils.isEmpty(query) ? s : query + "&" + s; + String str = UriComponentsBuilder.newInstance().queryParams(this.queryParams).build().encode().getQuery(); + query = StringUtils.hasLength(query) ? (query + "&" + str) : str; } if (query != null) { request.setQueryString(query); diff --git a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java index 0e1e81d93e2..05ea8d372fc 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java @@ -245,10 +245,10 @@ public final class ResponseCookie extends HttpCookie { @Nullable private String initDomain(String domain) { - if (lenient && !StringUtils.isEmpty(domain)) { - String s = domain.trim(); - if (s.startsWith("\"") && s.endsWith("\"")) { - if (s.substring(1, s.length() - 1).trim().isEmpty()) { + if (lenient && StringUtils.hasLength(domain)) { + String str = domain.trim(); + if (str.startsWith("\"") && str.endsWith("\"")) { + if (str.substring(1, str.length() - 1).trim().isEmpty()) { return null; } } diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java index 89a23b165b8..cf1b3ee3ee1 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpRequest.java @@ -38,7 +38,6 @@ import org.springframework.core.io.buffer.PooledDataBuffer; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.util.Assert; /** * {@link ClientHttpRequest} implementation for the Jetty ReactiveStreams HTTP client. @@ -62,9 +61,7 @@ class JettyClientHttpRequest extends AbstractClientHttpRequest { @Override public HttpMethod getMethod() { - HttpMethod method = HttpMethod.resolve(this.jettyRequest.getMethod()); - Assert.state(method != null, "Method must not be null"); - return method; + return HttpMethod.valueOf(this.jettyRequest.getMethod()); } @Override @@ -117,7 +114,6 @@ class JettyClientHttpRequest extends AbstractClientHttpRequest { public void succeeded() { DataBufferUtils.release(buffer); } - @Override public void failed(Throwable x) { DataBufferUtils.release(buffer); From ca7fb23432a4ad235c50fa01c72b5816aec38882 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 6 Oct 2020 15:31:46 +0200 Subject: [PATCH 4/4] Upgrade to Hibernate ORM 5.4.22, Hibernate Validator 6.1.6, Undertow 2.0.32, Checkstyle 8.36.2 --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 5e8494b41d8..65ef742f874 100644 --- a/build.gradle +++ b/build.gradle @@ -116,8 +116,8 @@ configure(allprojects) { project -> dependency "net.sf.ehcache:ehcache:2.10.6" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core:5.4.21.Final" - dependency "org.hibernate:hibernate-validator:6.1.5.Final" + dependency "org.hibernate:hibernate-core:5.4.22.Final" + dependency "org.hibernate:hibernate-validator:6.1.6.Final" dependency "org.webjars:webjars-locator-core:0.45" dependency "org.webjars:underscorejs:1.8.3" @@ -132,7 +132,7 @@ configure(allprojects) { project -> entry 'tomcat-embed-core' entry 'tomcat-embed-websocket' } - dependencySet(group: 'io.undertow', version: '2.0.31.Final') { + dependencySet(group: 'io.undertow', version: '2.0.32.Final') { entry 'undertow-core' entry('undertow-websockets-jsr') { exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec" @@ -326,7 +326,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.36.1" + toolVersion = "8.36.2" configDir = rootProject.file("src/checkstyle") }