Spring Boot scans Test configuration classes on start up - spring

I have a Spring Boot App with the main class as below.
#SpringBootApplication
#EnableAspectJAutoProxy(proxyTargetClass = true)
#EnableAutoConfiguration
public class Application extends SpringBootServletInitializer
The project structure is
App/
src/main/java
src/test/java
In the test package , I have a configuration class used for Integration testing and the class is marked as #TestConfiguration. I am noticing that this class is getting picked up on the server startup. I am using profile as dev on start up. Any idea why the test configuration classes are getting loaded on startup of the application. I need these classes to be scanned only during test phase.
This works well when i run java -jar command from command line, but fails during start up from STS eclipse.

Related

Deploy a war of Spring Boot application to the local Tomcat server: 404 response [duplicate]

This question already has answers here:
Tomcat 10.0.4 doesn't load servlets (#WebServlet classes) with 404 error [duplicate]
(2 answers)
Closed 1 year ago.
I generated a simple Greeting web application using Spring Initializr and choose war as the packaging type. Starting it from the terminal with mvn spring-boot:run and pointing my browser to http://localhost:8080/greeting returns the expected response.
I followed this article for the deployment steps and modified pom.xml so that to avoid including version numbers in the generated war:
<build>
<finalName>${artifactId}</finalName>
<plugins>
...
</build>
I build the war as usual with mvn clean installand got the expected demo-spring-web.war which I copied/pasted inside the apache-tomcat-10.0.4/webapp folder.
Then I started the Tomcat bu running catalina.sh run from the Tomcat bin folder.
Tomcat started and displayed the demo-spring-web.war to be successfully deployed:
11-Apr-2021 18:24:36.414 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR
Deployment of web application archive [/Users/serguei/soft/apache-tomcat-10.0.4/webapps/demo-spring-web.war] has finished in [1,286] ms
But when I tried to access the deployed application at localhost:8080/demo-spring-web/greeting, it returned 404 status.
What's wrong with that?
You must declare a run class that extends SpringBootServletInitializer, for deploy in war mode.Like this :
#SpringBootApplication public class AppTomcat extends SpringBootServletInitializer {
}
The default prepared/initialized application from spring initializer contains main() method initializing the application so that it can run in a stand alone mode and can be tested quickly.
In case you want to deploy it to another container you should make a servlet initializing the application.
So you should be extending the class having main method with SpringBootServletInitializer and remove main method.
The "mvn clean package" will fail if you have plugin "org.springframework.boot" in the .
I think following above two steps will make the built war deployable in external tomcat.
I had read an article some times back, may be that can also help: https://www.baeldung.com/spring-boot-war-tomcat-deploy

how to #autowire dao class created in project A to the rest controller class in Project B

I created a Springboot application with dao class, model and rest controller. it works fine.
now i want to create rest controller in separate project.
Project A : model + dao class
Project B: rest controller
in Project B pom.xml I included the Project A jar file under dependency
Now i m trying to autowire dao class from project A to the restcontroller class in Project B.
In the rest controller class (project B) i used #ComponentScan(basePackages="package where my daoclass is there")
But i am getting compilation error saying cannot resolve the symbol for the line daoclass dao;
I am new to spring and springboot. Not sure what is wrong.. please help me to understand it better
I am trying to do mvn clean package (project B)
You need to register the class as a bean in the spring context with the applicationContext.xml for projectB, otherwise projectB can't find the bean created by projectA.
For example, you should write following applicationContext.xml
<context:component-scan base-package="name.space.for.projectA"/>
You can also configure component-scan with annotations:
18. Using the #SpringBootApplication annotation
(a) Specify target packages as scanBasePackages
#SpringBootApplication(scanBasePackages={"name.space.for.projectA"})
or
(b) Specify target packages as #ComponentScan
#SpringBootApplication
#ComponentScan("name.space.for.projectA")
Check your jar file exists in local repository.
Open your local repository folder in setting files
<localRepository>Your Directory</localRepository>
And check your jar file is in there.
If file is not exist, try copy and paste it first.
And if Project B is Okay, then check your maven setting file.
Maven will always look in your local repository (usually found in ~/.m2/repository) for dependent jars.
Therefore you must execute:
mvn clean install
in projectA. This will copy your projectA-version.jar into your local repository, where projectB will be able to find it.

Eclipselink Static Weaving and Spring Boot is not Working

In a Spring Boot project we use Eclipselink as ORM. We configured the build to weave statically and to package as jar. The interesting thing is that starting the program with mvn spring-boot:run works without problem, but starting with java -jar archive.jar works only if all entities are listed in the persistence.xml. Without having the class in the persistence.xml I get the error:
java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [eltest.Customer] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>eltest.Customer</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
Also in the case, when we package the program as war, it starts without issues.
My questions are: Does the mvn spring-boot:runinvoke the static weaving at all, or does it weave at load-time? The same with the war deployment: does the war-build really invoke the static weaving, or is the weaving implicitly triggered, when the Tomcat starts the app? Is there a way to avoid listing the classes in the persistence.xml, and still go for statical weaving in a jar-packaging?
Here is an example:
https://github.com/gfinger/eltest
Build it with mvn clean package. If you start it with mvn spring-boot:run it uses Spring Data Rest to expose a Customer entity as REST resource. If you start it with java -jar target/static-eclipselink-0.0.1-SNAPSHOT.jar you get an error.

Spring WebApplicationInitializer (ServletContainerInitializer, #HandlesTypes) with Embedded Tomcat

I fail to understand why in the following minimal project my implementation of Spring's WebApplicationInitializer interface is found when running tests within Eclipse and IntelliJ, but not when using Maven (mvn clean test).
With Eclipse and IntellIJ I see INFO: Spring WebApplicationInitializers detected on classpath: [com.example.pack.DummyInitializer#26d678a4]
With mvn clean test I see INFO: No Spring WebApplicationInitializer types detected on classpath.
In the test I start an Embedded Tomcat:
String pathToWebXML = new File("src/main/webapp/").getAbsolutePath();
tomcat = new Tomcat();
tomcat.setBaseDir("embedded_tomcat");
tomcat.setPort(0);
tomcat.addWebapp("", pathToWebXML);
tomcat.start();
The web.xml references a ServletContextListener implementation which creates a new (and empty) AnnotationConfigWebApplicationContext.
I uploaded the example project to GitHub: https://github.com/C-Otto/webapplicationinitializer
As indicated in the comments, the classpath used by Maven Surefire (and Maven Failsafe) in the default setting is not scanned by Tomcat. Most classes are referenced using a MANIFEST.MF file inside a JAR file.
One option is to disable the useSystemClassLoader setting of the Maven plugins. However, this changes the details of the classloader, which may cause other problems.
As another option one could disable useManifestOnlyJar, which may cause problems on Windows machine.
In our project we decided to remove the initializer classes, and instead register whatever they were supposed to do manually. In a concrete example, as our implementation of AbstractSecurityWebApplicationInitializer was not found, we now register the security filter manually inside the contextInitialized method:
String filterName = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
servletContext.addFilter(filterName, new DelegatingFilterProxy(filterName)).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
You can tell Tomcat to include the jars that are referenced via the manifest file in the jar created by surefire. This can be done in context.xml setting the Jar Scanner attribute scanManifest to true. This is the default in newer versions of Tomcat as stated here: https://bz.apache.org/bugzilla/show_bug.cgi?id=59961.

Spring JUnit ContextConfiguration class path resource cannot be opened

I am using the latest version of Spring-Boot (spring boot starter web and test), in a gradle project. And this older unit test I use to have is no longer working.
The XML context file is located under src/test/resources/myTestContext.xml. But I get the error below when I try to run this as a Junit test in Eclipse (mars 4.5)
#ContextConfiguration(locations={"/myTestContext.xml"})
public class MyTest extends AbstractJUnit4SpringContextTests{
....
Caused by: java.io.FileNotFoundException: class path resource [myTestContext.xml]
cannot be opened because it does not exist at
org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]

Resources