I have a library that makes use of spring-jdbc, the library contains common utility methods that need to be standardized across multiple projects.
The library when used in other spring boot application causes the project to fail with no bean on type DataSourceConfuguration Exception.
I have read tips to exclude DataSourceConfiguration on #SpringBootApplication but that would mean making change on every application that uses the library regardless of whether the application needs a datasource or not.
#Configuration
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
The other option is to exclude DataSourceConfiguration in spring.factories of the library itself, but then it would stop the autoconfig ability of any application using the library and will have to manually define DataSource.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
Is there a possible way to make this situation work for the library and any other project that wants to use the library but doesn't have to define a datasource and still function like a normal Spring Boot Application ?
The below is from Spring Documentation
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
#Configuration
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
https://docs.spring.io/spring-boot/docs/1.3.8.RELEASE/reference/html/using-boot-auto-configuration.html
Related
I am developing a bunch of Java/Sprint Boot webservices that will all have several identical (ideally, reusable) Spring-based resources:
many annotation-based Spring Security configurations
several #Services and #Components
many annotation-based event handlers
annotation-based exception handler
#ControllerAdvice that extends ResponseEntityExceptionHandler
annotation-based configuration files (#Configuration)
Ideally I could place these in a library (shared JAR file) and reuse them across the different webservice projects. However I don't believe Spring Boot will scan the entire dependency graph of libraries and load them based on their annotations.
Does anybody know of a way to encourage Spring Boot to do this? For example if I package the following class into a reusable/shareable library JAR:
#ControllerAdvice
#Slf4j
public class ApiExceptionHandler extends ResponseEntityExceptionHandler implements ApiContractConstants {
// ... common exception handling code to be used by
// all services
}
And then pull that in to a Spring Boot webservice (via Maven/Gradle) as a runtime dependency, how do I get Spring Boot to scan, find and load that exception handler for me?
The description makes me think of #SpringBootApplication. The property scanBasePackages of #SpringBootApplication defines base packages to scan for annotated components.
#SpringBootApplication(scanBasePackages = {"org.example"})
What's going on
I am using Java, Springboot
I am trying to create a simple API.
I have a package called Example.
I have two sub-packages called config and rest.
In config is the class Application, which is my spring app.
In rest is the class TheController which is the rest controller
Currently when i run the app, Application and try and go to one of the get mappings i get a white label error page.
However if i move theController to the config package i do not get this error and it's plain sailing.
What I have tried
I have tried using an import statement.
com.Example.rest.* and com.Example.rest.TheControllerwith no results.
Any help would be appreciated :)
Add a #ComponentScan on your application class.
package com.example.config;
#SpringBootApplication
#ComponentScan(basePackages = "com.example")
public class SpringBootComponentScanApp {
}
I personally think it's a good idea to put your configuration in a sub-package "com.example.config" and not in the parent package "com.example", but you need to override Spring Boot's default component scan for that case.
See also https://www.baeldung.com/spring-component-scanning
Spring Boot will only scan for components (controllers, services, repositories, ...) starting from the package of the application class (annotated with #SpringBootApplication) and below.
So best to use com.example.Application, then you can use com.example.rest.TheController and things should work.
I am creating a few spring components and it would be a part of a library - jar.
I want the components to get loaded automatically by the applications that have the jar in the classpath.
#Component
public class AComponent {
}
I tried creating a configuration class and doing a component scan, but, the configuration is not loading.
#Configuration
#ComponentScan(BasePackages="")
public class ComponentConfig {
}
Can you please suggest a solution? It's a non-spring-boot application.
As you are writing a library, that uses Spring, I do not believe it is possible for the client applications to make zero changes. Your library has a collection of Spring beans that must be loaded into an ApplicationContext. At the very least, the clients will need to include your #Configuration/#Component classes (via scanning).
Good luck.
I have an application which connects to a zookeeper to perform operations on HBase. However, for Integration Tests, I have a class to create in-memory tables, and perform tests without trying to connect to said zookeeper.
I have defined a IntegrationTestAppConfig.class as follows:
#EnableAutoConfiguration(exclude = { AppConfig.class})
#ComponentScan
#Configuration
#EnableAsync
public class IntegrationTestAppConfig{
..... //this is where I create a bean for my HBaseConnectionManager to use my in-memory table environment
}
And, in my integration test class, I have the following:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = IntegrationTestAppConfig.class)
public class AHCLIManagerIT {
#Test
.....
}
Based on what I've read from the Spring-boot documentation, the integration test class should use IntegrationTestAppConfig.class for the application configuration.
However, when I run the Integration Test, I get an error saying connection to zookeeper timed out. In the stack trace, I see that the error occurred in AppConfig.java (my main class for app configuration), where it tries to create a HBaseConnection to the zookeeper.
I don't understand why my application is not using the App config class that I've defined in the annotations.
Is your AopConfig class actually an autoconfiguration class? Autoconfiguration classes are loaded by naming them in a spring.factories file in META-INF. The exclude attribute would only apply to those I believe. Auto configuration happens after regular app configuration anyways.
Also you have #ComponentScan on your config. If you really need to exclude AopConfig that would be the annotation I'd expect it to be on.
Though IMHO something doesn't seem right for doing a component scan in your tests
I have a project that uses spring-data-rest, and has a dependency project that only uses Spring Data. Both projects have spring data repositories and use #EnableJpaRepositories to implement their repository interfaces, but I only want to export the repositories in the parent project.
Here's my question: is there some way to configure Spring Data REST to only expose rest endpoints for resources in the parent project, without having to explicitly annotate every repository in the dependency project with #RepositoryRestResource(exported = false)?
If I can only do this with #RepositoryRestResource of disabling it, and worse yet, no other project with a different use case will be able to enable REST endpoints for those repositories, my dependency project will have to include Spring Data REST solely for theā¦
Looping back here as I was looking for this specific setting. It looks like this is now implemented. In this case, you would want to set spring.data.rest.detection-strategy=annotated to avoid default exposure.
All application.properties options:
# Exposes all public repository interfaces but considers #(Repository)RestResource\u2019s `exported flag.
spring.data.rest.detection-strategy=default
# Exposes all repositories independently of type visibility and annotations.
spring.data.rest.detection-strategy=all
# Only repositories annotated with #(Repository)RestResource are exposed, unless their exported flag is set to false.
spring.data.rest.detection-strategy=annotated
# Only public repositories annotated are exposed.
spring.data.rest.detection-strategy=visibility
References
3.5.1. Setting the Repository Detection Strategy
Common Application Properties
Currently there's no global switch for what you're looking for. I've filed this ticket for you for inclusion in the next major release.
Not sure if it is an option for you but package private repository interfaces are not currently exposed unless explicitly annotated. If you can make all those library repositories package protected that might be favorable over the explicit annotation.
As of version 3.4 use:
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
#Configuration
public class SpringRestConfiguration implements RepositoryRestConfigurer {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
config.disableDefaultExposure();
}
}