In my Spring Boot project (1.5.6.RELEASE) that I build using gradle, I want to include some custom properties. The approach laid out in the documentation does not seem to work (on build, I get: Could not set unknown property 'additional' for task ':properties' of type org.gradle.api.tasks.diagnostics.PropertyReportTask.):
springBoot {
buildInfo {
properties {
additional = [
'a': 'alpha',
'b': 'bravo'
]
}
}
}
Luckily this approach, which I found here, does work for me (no compile error and I'm then able to access the property from my code):
springBoot{
buildInfo {
additionalProperties = [
'testpropertykey': 'testpropertyvalue'
]
}
}
But, since the former is the "officially" documented approach, I would prefer to take that approach. How would I get the former approach to work? I assume I'm missing something - unless the documentation is wrong or maybe this changed from Spring Boot 1.5.6.RELEASE.
The docs you linked are for the current version of the plugin which aligns with the current GA version of Spring Boot: 2.1.7
Version 1.5.x of the plugin does have a additionalProperties field: https://github.com/spring-projects/spring-boot/blob/1.5.x/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java#L66
The 2.1.x version does not and you use properties instead: https://github.com/spring-projects/spring-boot/blob/2.1.x/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java#L45
Suggest you migrate/upgrade to Spring Boot 2.1.x or 2.2.x when that is released soon since 1.5.x has already reached EOL: https://spring.io/blog/2018/07/30/spring-boot-1-x-eol-aug-1st-2019
Related
This is a really simple question, but hard to find the answer.
I'm using kotlin DSL and gradle (so build.gradle.kts and settings.gradle.kts).
I'm using netflix-dgs and spring boot like so:
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter")
And of course a few others (e.g. extended scalars).
I've figured out how to edit my generateJava task:
tasks.withType<com.netflix.graphql.dgs.codegen.gradle.GenerateJavaTask> {
schemaPaths = mutableListOf("$projectDir/src/main/resources/schema")
packageName = "envoy.roomba.netflix.dgs.generated"
}
How do I edit the rest of the configuration mentioned here? https://netflix.github.io/dgs/configuration/.
I tried a gradle.properties file, I've looked briefly at extending #DgsAutoConfiguration, but without any luck.
you can configure properties in the applciation.yml file or application.properties whatever is relevant in your case. Since you are using spring boot, DGS will pick up properties from your application properties file.
I am involved in a review task of an older project. The task is to update certain libraries to more recent versions. This project successfully used load-time-weaving with spring (4.3.14.RELEASE) together with AspectJ (1.9.0) and Tomcat 8.0.20 under JDK 8 with. Now spring shall be updated to the most recent version (5.3.3 at the moment) and also the Tomcat version shall be lifted to a recent version (9.0.37 targeted for the moment). The server shall be running under JDK 11. After upgrading the libraries, we recognized that AspectJ was not working anymore. So I started to debug into this. AspectJ is activated from an XML configuration like this:
<context:load-time-weaver />
Debugging the startup of the container a stumbled over this piece of code in org.springframework.context.config.LoadTimeWeaverBeanDefinitionParser:
protected boolean isAspectJWeavingEnabled(String value, ParserContext parserContext) {
if ("on".equals(value)) {
return true;
}
else if ("off".equals(value)) {
return false;
}
else {
// Determine default...
ClassLoader cl = parserContext.getReaderContext().getBeanClassLoader();
return (cl != null && cl.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) != null);
}
}
As we do not provide any attribute to the XML tag, AspectJ is in auto-detect mode causing the code in the else branch to be executed. There the reference to the classloader is null, leading to AspectJ being disabled.
An attempt to explicitly activate AspectJ by passing <context:load-time-weaver aspectj-weaving="on"/> had no effect in the end. AspectJ was set active and the definitions were loaded but none of the Aspect definitions (META-INF/aop.xml) were detected applied. As we have changed nothing so far by means of the AspectJ functionality or package structure, something must have changed in spring from 4.3.14 to 5.3.3) or AspectJ (1.9.0 to 1.9.4). A quick view in the GitHub repo showed my only one significant change. But debugging this, the classloader used before the change was also null.
Has anyone had similar problems getting AspectJ to work this way? It looks to me that the problem is detecting the aop.xml files on the classpath.
EDIT:
I have made some more research using different combinations of JDK and Tomcat versions. The problem is not related to those two. When upgrading spring version by version, I found out that it worked fine till 5.1.20.RELEASE. Starting with 5.2.0.RELEASE my problems start. Meanwhile I have AspectJ logging active so I can see that some classes are woven but the majority of those classes I expect being woven, are not.
This was caused by a regression in spring framework since 5.2.0.RELEASE. Here is the issue for that.
PROBLEM:
RESEARCH: At https://gitlab.com/ZonZonZon/simple-axon.git I've made up a simple Axon-app to show that JAR-artifact built with Gradle-plugin com.github.johnrengelman.shadow doesn't autoconfigure Axon beans when (when run as JAR). Though it runs fine under Intellij.
From project root in terminal:
run gradle clean build shadowJar;
java -jar build/simpleaxon.jar;
Stacktrace is enclosed here. I expect that Axon Autocongiguration provides beans like CommandBus, Snapshotter and other by default.
QUESTION: How to autoconfigure default axon beans in a fat jar?
So, this took my some investigation to get a hunch what is going wrong, but I know what the problem is.
Quick notice, it's not an Axon specific thing, rather the plugin you are using.
I ran your sample project and indeed ended up with the same result; no Axon beans were being wired, ever. That led me to investigate the process of creating fat JAR's step by step. First Maven, then Spring Boot with Maven, then Gradle with Spring Boot and finally with the Shadow plugin you are referring too.
This endeavour landed me on this issue, which states as much as "projects which require the use of META-INF files need to add this to the shadow plugin, and this should be documented".
The portion referenced through this is the following:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
// Left out all other specifics from your 'build.gradle' file
shadowJar {
// Required for Spring
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories' ]
mergeStrategy = "append"
}
setArchiveFileName("simpleaxon.jar")
getDestinationDirectory().set(new File(projectDir, "./build"))
}
After adding that piece of logic to your build.gradle file, I could run your sample project as expected.
I've hit a similar issue when using Axon in a multimodule Gradle project. The app would not work when packaged and worked fine in IDE. The exact error I was getting was
org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 0 in handler
The reason for this was because ParameterResolverFactories were not loaded due to the META-INF/services resources not being resolved correctly in the shadow jar plugin as #Steven hinted.
I've managed to fix it with simply (using Kotlin DSL in Gradle):
tasks.shadowJar {
mergeServiceFiles()
}
#Steven 's solution was the only one working for me, after searching for a long time for other solutions.
The Gradle Kotlin Version looks like this https://github.com/spring-projects/spring-boot/issues/1828#issuecomment-607352468:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
}
...
tasks.shadowJar {
// Required for Spring.
// The shadowJar plugin should merge the services correctly, but it doesn't!
mergeServiceFiles()
append("META-INF/spring.handlers")
append("META-INF/spring.schemas")
append("META-INF/spring.tooling")
transform(
PropertiesFileTransformer().apply {
paths = mutableListOf("META-INF/spring.factories")
mergeStrategy = "append"
})
}
I have written a Gradle Plugin that contains a bunch of common setup configuration so that all of our projects just need to apply that plugin and a set of dependencies. It uses the Spring Dependency Management Plugin to setup the BOM imports for Spring as shown in the code snippet below:
trait ConfigureDependencyManagement {
void configureDependencyManagement(final Project project) {
assert project != null
project.apply(plugin: "io.spring.dependency-management")
final DependencyManagementExtension dependencyManagementExtension = project.extensions.findByType(DependencyManagementExtension)
dependencyManagementExtension.imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE"
}
}
}
Whilst that still works in Gradle 5.1 I wanted to replace the Spring Dependency Management Plugin with the new dependency mechanism for BOM Imports so I updated the above to now be this:
trait ConfigureDependencyManagement {
void configureDependencyManagement(final Project project) {
assert project != null
project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
}
}
Unfortunately that change means none of the dependencies defined by these BOMs are being imported and I get errors like these when building projects?
Could not find org.springframework.boot:spring-boot-starter-web:.
Required by:
project :
Could not find org.springframework.boot:spring-boot-starter-data-jpa:.
Required by:
project :
Could not find org.springframework.boot:spring-boot-starter-security:.
Required by:
project :
Am I correct in thinking the Spring Dependency Management Plugin is no longer needed with Gradle 5.1 and if so then am I missing something for this to work?
The platform support in Gradle 5 can replace the Spring dependency management plugins for BOM consumption. However the Spring plugin offers features that are not covered by the Gradle support.
Regarding your issue, the problem comes from the following line:
project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
This will simply create a Dependency, it still needs to be added to a configuration. by doing something like:
def platform = project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
project.dependencies.add("configurationName", platform)
where configurationName is the name of the configuration that requires the BOM. Note that you may have to add this BOM to multiple configurations, depending on your project.
I'm trying to use the Spring DSL functionality in a Grails plugin. However, it doesn't work. Here's what I have in my plugin's conf/spring/resources.groovy file:
import org.springframework.aop.scope.ScopedProxyFactoryBean
// Place your Spring DSL code here
beans = {
baseSvcProxy(ScopedProxyFactoryBean) {
targetBeanName = 'baseService'
proxyTargetClass = true
}
}
However, it seems to be completely ignored. If I move the exact same code to the application's conf/spring/resources.groovy file everything works perfectly. Is there something that needs to be done differently for plugins for this to work?
In order to modify the spring context from a Grails plugin you need to use the doWithSpring section of your plugin by hooking into the runtime configuration. Resources.groovy is ignored in plugins.