Spring Boot ehcache in multi maven project - maven

Im trying to use multiple ehcahe.xml configuration files in place of modules which will use defined caches.
When is the ehcache.xml configuration placed under resources of app-web module from where the spring boot application is started it works fine with #EnableCaching.
#SpringBootApplication
#Import({ CommonApp.class, CoreConfig.class})
#EnableSwagger2
#EnableCaching
public class WebApplication extends WeblogicMvcConfigurerAdapter {
}
But when is the configuration placed under the app-core module and #EnableCaching is moved under CoreConfig which is imported by WebApplication it fails on runtime.
#Configuration
#ComponentScan
#EnableCaching
public class CoreConfig {
}
When #Cacheable method is called I'm getting
java.lang.IllegalArgumentException: Cannot find cache named 'systemParameterCache'
My idea is that every module can have own ehcache.xml configuration with the caches which belong to that module.
Is it possible to use like that? What I'm doing wrong?
Thanks!

It is possible. But I wouldn't recommend that. One cache manager in an application is enough. Having many is resource consuming for nothing. If you have trouble giving different names to your caches, I suggest that you use a module prefix.
Then, I'm not sure what you mean by modules. #EnableCaching is expected to be specified once in an application.
But if it's only specified on CoreConfig it should work. However, you still need to create systemParameterCache in your cache configuration. It seems to be your problem here.

Related

Springboot build not working because of test configuration

I have started a spring boot project using start.spring.io.
But I am getting this error-
I have read various articles on the internet about this issue and they all say about putting my tests in the same package as my Main class.
But I already have the same.
Could you point out what is wrong with my configuration?
The exception is pretty clear: You are missing a configuration for your spring context. What you need to do is to add the configuration classes for your context like so:
#SpringBootTest(classes = { TestConfiguration.class })
whereas your TestConfiguration class must be annotated with
#Configuration
and/or
#EnableAutoConfiguration
There you can add configurations to your liking. You can of course also use your DatabaseApplication class as Configuration although Im wouldn't recommend that.
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
Make Sure your DatabaseApplication class is annotated with #SpringBootApplication .

Spring AOP aspect doesn't get applied if included from an external jar with different package name

I have a spring boot rest service that included an external project in pom as it's dependency. That external project is basically a jar that has spring AOP code.
The base package in my main application that includes this external jar with spring AOP code is x.y.z
The class in external jar where the #before advice is, is under the package a.b.c
With this class under a.b.c package, it doesn't get recognized by the main application where I want to use the spring aop implementation and apply the aspect. However, when I change it's package from a.b.c to x.y.z (which I really can't do in real life) it works fine.
I know that in spring boot service which happens to be the including service, it scans everything under root package given in the application class, x.y.z in this case and that is why aspect works fine if it's class is under x.y.z.
however, the problem is that this spring app jar will be used across multiple applications. So changing package name like this is not an option.
Is there a way to accomplish this without changing the package name of the class where spring app code is ?
Probably component scan is only activated for your application class packages by default. You can extend it to multiple packages, including the aspect package:
XML style configuration:
<context:component-scan base-package="x.y.z, a.b.c" />
Annotation style configuration:
#ComponentScan(basePackages = {"x.y.z", "a.b.c"})
Disclaimer: I am not a Spring user, only an AspectJ expert. I just knew that you can configure component scan, googled the syntax for you and hope it is correct.
Please define the bean (of jar project )inside main application. Give the #ComponentScan(basePackages = {"x.y.z", "a.b.c"}) as well as #EnableAspectJAutoProxy. Also include below piece of code.
ex:
` #Bean
public LoggingHandler loggingHandler()
{
return new LoggingHandler();
}`
Also annotate external jar code with:
`#Aspect
#Component
public class LoggingHandler {`
What #kriegaex suggests is correct. In addition to that, please make sure you are using #Component along with #Aspect. Since #Aspect is not a Spring annotation, Spring won't recognize it and hence your aspect won't be registered. So, using #Component is mandatory to getting aspects to work in Spring environment.

Wiring a bean from dependency module

I have created a configuration project which essentially creates couple of beans with configuration stereotype. Then, I want this project to be reused across by my clients.
I have added this config project as a maven dependency, but my client project is not having those beans i have created as part of configuration project.
Could someone help
Ok, the answer is the following: you should place
#ComponentScan("you.configurations.base.package")
on one of your configuration (in the current application, one that #SpringBootApplication sees) or on the class with #SpringBootApplication annotation.
The explanation is as follows: #SpringBootApplication under the hood contains #ComponentScan without specifying a base package. That means that it says to Spring to scan the package where the class annotated with #SpringBootApplication resides and all the packages recursively. And that's it. If you place you #Configuration somewhere there - it will create it during startup, otherwise not.
We can resolve this by enabling spring-boot autoconfiguration
Create classpath->resources->META-INF->spring.factories file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=[add your class with you need to be loaded during application load time]

Spring boot auto configuration with dependency and without #ComponentScan

Spring boot provides #ComponentScan to find packages to be scanned.
I am building a library which has #RestControllers inside with package com.mylib.controller. There are other classes as well with stereotype annotations in different packages.
So, if some one is developing SpringBoot Application with com.myapp base package.
He uses my library in his application. He need to mention #ComponentScan("com.mylib") to discover stereotype components of library.
Is there any way to scan components without including library package in #ComponentScan?
As spring-boot-starter-actuator expose its endpoints just with dependency, without defining #ComponentScan. OR any default package which is scanned regardless of application base package.
You could create a Spring Boot Starter in the same style as the Spring Provided Starters. They are essentially a jar'd library with a a spring.factories file pointing to the #Configuration class to load with some other annotations on there to provide overriding/bean back off (#ConditionalOnMissingBean) and generally provide their own #ConfigurationProperties.
Stéphane Nicoll provided an excellent demo of how to build one.
https://github.com/snicoll-demos/hello-service-auto-configuration
It is also documented in the Spring Boot documentation. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
The library approach would also work but I see no benefit in not making it a starter. Additionally for any library/starter I'd recommend dropping the #ComponentScan and just defining the beans in a #Configuration. This will work for sterotypes like #RestController etc. will function as normal if you create an #Bean out of it in a configuration.
Spring boot starter are special artifacts designed by Spring and used by Spring.
You can check that in the source code that contains mainly a
spring.provides file :
provides: spring-boot-actuator,micrometer-core
I don't know the exact way to process in the same way as Spring Boot Starter but as probably acceptable workaround, you could define in your jar a #Configuration class that specifies #ComponentScan("com.mylib").
#Configuration
#ComponentScan("com.mylib")
public class MyLibConfig {
//...
}
In this way, clients of the jar need "only" to import the #Configuration class :
#Import(MyLibConfig.class)
#Configuration
public class ClientConfig{
//...
}

spring-boot without #SpringBootApplication

I am attempting to migrate a spring, non-boot, app to a boot app. The current one builds a war file. Following these instructions, I am walking through the steps to migrate.
I am finding that the #SpringBootApplication annotation forces a lot of things to fail. For instance, it tries to auto config security when I really need the existing xml security config to remain as is. I found that I can override #EnableAutoConfiguration and exclude configuration classes (.i.e. SecurityAutoConfiguration.class). But I am finding it is doing this a great deal for the items I already have on my classpath. I decided it would be better to remove #SpringBootApplication and replace it with just #Configuration, #ComponentScan and #ImportResource to load my original context xml. The class extends SpringBootServletInitializer so that I can register my custom servlets and filters.
What I have found, it now no longer knows to load the application.yml or bootstrap.yml. What triggers auto configuration of these files? Do I fall back to loading with the traditional properties placeholder configurers? I want to avoid this as the next step is to hook it up to spring cloud config to centralize the management of the application configuration.
#SpringBootApplication is a alternative for #Configuration, #EnableAutoConfiguration and #ComponentScan.
Probably you want use #Configuration + #ComponentScan. If you want load xml configuration you can use: #ImportResource annotation.
If you want use autoconfiguration, but you can disable a few auto configurations, eg:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Details:
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-configuration-classes.html
http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html

Resources