My problem - for the study Spring I write a not great application composed of several modules (multimoduls).
module1
src
entity
dao
resource
spring-config.xml ---> This is DataSource, SessionFactory, TransactionManager
module2
src
entity
dao
resource
spring-config.xml ---> This is DataSource, SessionFactory, TransactionManager
service1
src
service_for_module1
resource
spring-config.xml ---> Initialization bean Service1 (used for module1)
service2
src
service_for_module2
resource
spring-config.xml ---> Initialization bean Service2 (used for module2)
web
src
ManagerBeanForJSF
web
pages
WEB-INF
spring
spring-config.xml ---> Import all spring config from modules
I have exception org.hibernate.hql.internal.ast.QuerySyntaxException.
When I did not have module2 - all worked successfully. Error associated with duplication of SessionFactory and TransactionManager?
Can you give an example of application in Spring composed of several modules.
Thanks.
I would suggest you use a maven project and post the poms so we can clearly see the dependencies between the projects.
As your question is a bit incomplete I can only guess you're using maven. Right? Anyway, when using Spring you should definitely, as you already wrote yourself, define the infrastructural part in one common module. Spring provides the possibility to include other context files. Even with wildcards. So you could define one singular main context file that loads those of all others in one go. The best is to have some sort of naming conventions, so that each module can easily contribute its context files.
Related
I have a Spring Boot project with Hibernate.
The project does not have a hibernate.cfg.xml file.
The project also does not have an applicationContext.xml file.
Nevertheless, all works well.
However, when I start adding new hibernate entities, then things go wrong. For some reason, the system only finds them when I put them inside the package of the other hibernate entities.
So, this leads me to believe that I do need additional configuration to help the auto-discovery mechanism. But what is the state-of-art in 2020 ? (I assume that the above xml files are now deprecated).
If you use spring + hibernate then it solved by #ComponenScan annotation.
If pure hibernate then I think you need persistence.xml
EntityManager is the class that performs database interactions in JPA.
It is initialized through a configuration file named persistence.xml.
This file is found in the META-INF folder in your CLASSPATH, which is
typically packaged in your JAR or WAR file. The persistence.xml file
contains:
The named "persistence unit," which specifies the persistence framework you're using, such as Hibernate or EclipseLink.
A collection of properties specifying how to connect to your database, as well as any customizations in the persistence
framework
A list of entity classes in your project
I totally overlooked these annotations which were present on the SpringBootApplication class.
#SpringBootApplication(scanBasePackages = {"com.domain.foo.bar.*"})
#EnableJpaRepositories(basePackages ={"com.domain.foo.bar.*"})
#EntityScan(basePackages ={"com.domain.foo.bar.*"})
public class SpringBootApplication extends SpringBootServletInitializer {
}
I needed to add my packages here.
I'd like to get help in setting up a multi-module Maven project using Spring Boot.
Correct me if I'm wrong but I've read that Spring-Boot reads the start main Application (Annotated with #SpringBootApplication and ran with SpringApplication.run) and finds the necessary classes through reflection. Which means that it first accesses the start class and then proceeds to find the controllers, models, repositories. If so, how do I set up the dependency in the pom.xml of each module if I had a project structure like this:
app
--src
--pom.xml
core
--pom.xml
--models
----/pom.xml
--controllers
----/pom.xml
--repositories
----/pom.xml
pom.xml
Please have a look complete guide how to create multi module project in spring boot.
https://spring.io/guides/gs/multi-module/
Spring boot will component scan from the package of the class annotated with #SpringBootApplication. Component scannign means that it is looking through the classes under that package recursively, analyzing annotations, and wiring up anything it recognizes. This can include controllers, simple variables with #Value annotations, members with #Autowired, and a host of other things.
You can actually jump into the source for the #SpringBootApplication annotation and see that it expands to numerous other annotations, #ComponentScan being one of them.
If all of your modules are in a sub-hierarchy package wise from there, then they will be scanned properly anyway. Often though, sub-modules will be in a slightly different package hierarchy. In this case, you can explicitly specify #ComponentScan() in your code and inside the () you can list the base packages to component scan from.
Whether or not its a sub-module doesn't matter much at this point; its just like scanning classes in any other library you're including.
General Advice
Also, just FYI - Multi module projects can get a little hard to manage (speaking from numerous separate experiences). They can be very good if used properly though. If you're a beginner to Maven though, it may be wiser to keep separte, well-defined projects with a proper release cycle and just import them as normal dependencies.
So, I'm not for or against them, but just make sure you understand them well going in :).
I have a GitHub project where I configured a multimodule maven project:
https://github.com/cristianprofile/spring-boot-mvc-complete-example
This is Example project maven module structure:
Spring mvc rest maven module ---> service maven module ---> repository maven module
The main module should be configured like this (Spring mvc rest layer):
#SpringBootConfiguration
#EnableAutoConfiguration
//spring mvc module auto scan only its package
#ComponentScan(basePackageClasses = HelloWorldController.class)
//It needs Service bean so it will import ConfigurationService.class from
// Service maven module
#Import({ConfigurationService.class})
Complete class:
https://github.com/cristianprofile/spring-boot-mvc-complete-example/blob/develop/spring-boot-mvc-rest/src/main/java/com/mylab/cromero/controller/Application.java
It will only scan its package :
HelloWorldController.class --> com.mylab.cromero.controller;
This Rest layer use a service maven module so it is necessary to add dependency:
<dependency>
<groupId>com.mylab.cromero.core</groupId>
<artifactId>mylab-core-service-impl</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
Complete pom file:
https://github.com/cristianprofile/spring-boot-mvc-complete-example/blob/develop/spring-boot-mvc-rest/pom.xml#L16
ConfigurationService.class from service maven module autoscan its packages and it will import ConfigurationRepository.class (Repository maven module)
#Configuration
//It needs repository's bean so it will import ConfigurationRepository.class from
// Repository maven module
#Import(ConfigurationRepository.class)
//service layer module auto scan only its package
#ComponentScan(basePackageClasses = ConfigurationService.class)
public class ConfigurationService {
}
Complete Service maven module code:
https://github.com/cristianprofile/spring-boot-mvc-complete-example/blob/develop/mylab-core/mylab-core-service-impl/src/main/java/com/mylab/cromero/service/ConfigurationService.java#L12
Service maven module layer has a dependency with maven repository module:
https://github.com/cristianprofile/spring-boot-mvc-complete-example/blob/develop/mylab-core/mylab-core-service-impl/pom.xml#L38
Repository module will auto configure jpa and domain classed:
#Configuration
#EnableJpaRepositories(basePackages = "com.mylab.cromero.repository")
#EntityScan(basePackageClasses=Base.class)
#ComponentScan(basePackageClasses = BaseRepository.class)
public class ConfigurationRepository {
}
I have a Spring boot project which is packaged into jar and it functionalities are related to MQ and database. I want to now host a webservice on that project however I cannot use #EnableAutoConfiguration or #SpringBootApplication. The webservice to be created is a simple GET service that will return a integer value. I have tried following steps but still the webservice doesnt start.
Added Spring-webmvc, spring-web, spring-boot-web ,spring-tomcat jars to pom.xml
Changed the artifact type from jar to war in pom.xml
Added #EnableWebMvc in the config class
Added a class with #Controller and #RequestMapping
Created a bean for EmbeddedServletContext for Tomcat.
What have I missed?
Some blogs mentioned about creating a WebApplicationContextInitializer and some mentioned about creating a Dispatcher servlet.
My question is what all beans do I need to manually create to bring up my webservice (as I cannot use EnableAutoConfig)
This may be an impossible task, but here goes...
Is it possible to register a spring bean, by (ONLY) adding a jar to the classpath of a spring-boot application?
Scenario: I would like to create a non-intrusive plugin jar, which when imported into a spring-boot project's classpath, will automatically be picked up and provide a service (e.g. via a RestController).
Constraints
I don't want to change or reconfigure the existing spring-boot application (i.e. no additional scan paths or bean config).
I don't have any knowledge of the target spring-boot application's package structure/scan paths.
I guess I was hoping that by default Spring scan's its own package structure (i.e. org.springframework.** looking for the presence of database libs, etc) and I could piggy-back off that - I haven't had any luck (so far).
I've setup an example project in github, to further clarify/illustrate my example and attempts.
** Solution Addendum **
This bit that got it working, was to add the following file, which points to an #Configuration config file...
plugin-poc\src\main\resources\META-INF\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.thirdpartyplugin.PluginConfiguration
I think in such cases you would try to add a spring auto configuration that is annotated with #ConditionalOnClass to be only evaluated if the given class is on the classpath. This class can register the bean and would just be evaluated if the conditional evaluates to true
Here is the relevant part of the spring boot documentation : Creating your own auto-configuration
I created a cxf/spring project with:
mvn archetype:create -DarchetypeGroupId=org.apache.cxf.archetype -DarchetypeArtifactId=cxf-jaxws-javafirst
The resulting project has a HelloWorld.java interface annotated as a #WebService, and a HelloWorldImpl.java annotated with an endpointInterface=mypackage.HelloWorld.
There's a beans.xml file containing:
<jaxws:endpoint
id="helloWorld"
implementor="mypackage.HelloWorldImpl"
address="/HelloWorld" />
If I want to add more services, it looks like I'm expected to keep adding new endpoints in beans.xml. Since the classes are already annotated as #WebService, why can't it auto-discover any new services within some package / search path? Is there some way I can configure this project to do that?
Basically, I'm just trying to avoid repeating myself. The information is already going to be in the annotations so I don't want to have to edit additional files each time I add a service.
If I remove the jaxws:endpoint tag in beans.xml, and then mvn install tomcat:run, localhost:8080/myArtifactId just shows me a page saying there are not services defined.
When you use the CXF you should know that all the endpoints you added are managed by the CXFServlet that uses Spring context to find them out. beans.xml is a Spring context's config file. So if you remove the <jaxws:endpoint/> node from that file your Spring context and hence the CXFServlet will have no way to find your service endpoints.