how load external configuration class in spring boot - spring-boot

I have a spring boot application
The structure of my application is:
src
main
java
org
Application.java
service
--another classes are here
Application.java
package org.baharan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) throws Throwable {
SpringApplication.run(Application.class, args);
}
}
Another confirguration class files sush as oracle config and security config are in another application(is named core) is added in my pom.xml
<dependency>
<groupId>org.baharan.amad</groupId>
<artifactId>core</artifactId>
<version>1.0-releases</version>
<type>war</type>
</dependency>
When i build my application, all of classes and properties files of core application are added in my target by overlay maven
When i excute Application.java,spring boot couldn't find any config class isn't in my application but they are in core(after build all of them is added in my target)
In other word how spring boot load configuration classes which dont exist in current application.
please help me.

If they're spring configs you can still use #ComponentScan to load in other bean configs e.g.
#ComponentScan("classpath*:com.myorg.conf")
and
#ComponentScan("classpath*:conf/appCtx.xml")

Related

I have 2 CommandLineRunner in same Spring boot

I have 2 classes in spring boot that implement command line runner. They basically look like this:
#SpringBootApplication
#ComponentScan("com.xxxx")
public class Application implements CommandLineRunner {
and the second looks like:
#SpringBootApplication
#ComponentScan("com.xxxx")
public class ApplicationWorklfow implements CommandLineRunner {
They compile fine. But when I try and run it with java -jar, I get an error presumably as spring does not know which one to run.
is there a command that I can use that will tell the jar which application I am trying to run?
You can have any number of CommandLineRunner beans but there should be only one entry point class that can have #SpringBootApplication annotation. Try by removing #SpringBootApplication annotation on ApplicationWorklfow.
PS:
It seems your main requirement is to conditionally enable one of 2 CommandLineRunner beans. You can have only one Application class and enable CLR beans conditionally either using #Profile or #ConditionalOnProperty etc.
Having multiple entry point classes with #SpringBootApplication annotation is not a good idea.
#SpringBootApplication
public class Application {
}
#Component
#Profile("profile1")
public class AppInitializer1 implements CommandLineRunner {
}
#Component
#Profile("profile2")
public class AppInitializer2 implements CommandLineRunner {
}
Now you can activate your desired profile as follows:
java -jar -Dspring.profiles.active=profile1 app.jar
With profile1 activated, only AppInitializer1 will run.
PS: PS:
If for some reason you still want to configure mainClass you can do as follows:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
You might leverage Maven profiles to provide different classes for different profiles. See https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/usage.html for more info.

Deploying SpringBoot (rest services) war via IntelliJ on Tomcat gives 404's

Starting a small SpringBoot application by running the application (directly), the REST service localhost:8080/xyz/a gives a correct JSON result.
Via IntelliJ I configured a Tomcat server. I added this WAR with a context root of '/contextroot'. So I expected the URL REST to be localhost:8080/contextroot/xyz/a. This keeps on getting 404 errors.
Can you help me getting the right configuration or URL?
Is there a way to see which URL's are mapped from the controller to the URL's? Or: how can I solve these mapping issues more easily (from Tomcat)?
In the Maven Pom.xml I have:
<groupId>nl.xyz</groupId>
<artifactId>contextroot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>contextroot</name>
<packaging>war</packaging>
The within is also contextroot.
#Jonhib - thank you for helping.
The problem was the way I deployed a SpringBoot (jar) application as a WAR.
Take these 3 steps to change a SpringBoot standard application into a deployable (old fashioned) WAR. This is needed because I deploy it together with a Angular4 application.
Step 1 - Change the standard SpringBoot application:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application .class);
}
public static void main(String[] args) {
SpringApplication.run(Application .class, args);
}
}
Change the target of the building process from 'jar' into a 'war'.
<packaging>war</packaging>
Add a new dependency into the pom.xml maven file:
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
...
</dependencies>

Spring Boot: Running as a Java application but classpath contains spring-web

I've successfully managed to create a Spring boot application that runs as a Java application as follows:
#SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication springApplication = new SpringApplication();
springApplication.setWebEnvironment(false);
springApplication.run(Application.class, args);
}
The problem is that my application requires the spring-web module as it is a client to a REST service.
Once I add the spring-web module I get an error:
Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
How can I get it to run as a Java application with spring-web on the classpath
I have "same setup" as you - command line spring boot app that uses RestTemplate from spring-web and everything works well. Maybe it is just that I use "full" spring web starter.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(and just slightly different main but it shouldn't be a difference)
SpringApplication app = new SpringApplication(MyApplication.class);
app.setWebEnvironment(false);
app.run(args);

multi module maven project module expose as soap web service

I have a multi module maven-spring project. Following is the structure-
ParentService
---ChildService-service
---ChildService-core
---ChildService-web
---ChildService-wsClient
---ChildService-mongo
I have created a new module called ChildService-wsService where I will write methods and expose as Axis2 SOAP web service. I have been able to write independent methods in classes of this module project and expose as service but I want to call methods of ChildService-service module.
When I try to call methods of ChildService-service module it gives me errors like NoClassDefFoundError.
Following is sample code--
public class HelloWorld {
#Autowired
private ITestService iTestService;
#Autowired
ICommonService commonService;
public String getVal(String s){
return s+"...testing...";
}
public String getValFfmService(){
iTestService=new TestServiceImpl();
return iTestService.test();
}
I am getting error as following--
Error: java.lang.NoClassDefFoundError: com/service/test/business/ITestService at java.lang.Class.forName0
If I include following line in class then also I am getting classnotfound error.
extends SpringBeanAutowiringSupport
You need to include your other projects that you need as dependencies, for instance, in your pom.xml:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>ChildService-service</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
...
</dependencies>
Then you need to install these dependencies in your local repository (mvn clean install will do it), or, in Eclipse, you need to activate Workspace resolution (right click on your module, Maven > Enable Workspace Resolution).

Spring Boot Application not reading application.properties file when using Maven test

UPDATE:
I realized a couple of things now. My application.properties file is being loaded properly because I verified via the /env path (thanks Dave) that my DB properties are being loaded. The problem appears to be that when I run it using the Spring Boot maven plug-in, it fails to initialize my dataSource.
mvn spring-boot:run
This then causes my application to blow-up with errors because other beans can't get initialized. The odd thing is it runs fine from Eclipse.
I have a class called DataService that extends JdbcTemplate. In my DataService constructor, I inject the DataSource.
#Component
public class DataService extends JdbcTemplate {
#Autowired
public DataService(DataSource dataSource){
super(dataSource);
}
...more custom methods
}
I use this DataService class in other beans to perform DB operations. My DataSource is defined in my application.properties file
spring.datasource.url: jdbc:h2:tcp://localhost/~/testdb2
spring.datasource.driverClassName: org.h2.Driver
This is my Application.java class
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableWebMvcSecurity
#EnableAsync
#EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I first realized this when I was attempting to run jUnit tests from Maven using
mavent test
I thought it just had to do with how it was executing the jUnit test cases however it is also occurring when I simply try to run the application using maven.
My JUnit4 test class is defined as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes={Application.class})
#WebAppConfiguration
public class QuestionRepositoryIntegrationTests {
...methods
}
I used the example from the Spring Boot how-to docs (https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html)
When I run this JUnit class from Eclipse, it works just fine. When it executes from maven, it starts to act up as I described above.
Try to define the <resources> tag in the build section in your pom, setting path for resource directory where is application.properties:
<build>
<resources>
<resource>
<directory>resources</directory>
<targetPath>${project.build.outputDirectory}</targetPath>
<includes>
<include>application.properties</include>
</includes>
</resource>
</resources>
</build>
You can configure your main datasource as the following, I'm using mysql here. But you can use your own datasource. you can configure the following in your application.properties inside src/main/resources
spring.datasource.url = jdbc:mysql://localhost:3306/dsm
spring.datasource.username = root
spring.datasource.password = admin123
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
To run test inside your application you can either use the same datasource or create application-test.properties inside src/test/resources and it's possible to configure test data source over there.
Just add the following statement;
#TestPropertySource("classpath:application.properties")
To your test class. I am assuming you have your application.properties file under src/test/resources
Here is my working example;
#RunWith(SpringJUnit4ClassRunner.class)
#TestPropertySource("classpath:application.properties")
public class TestTwitterFeedRoute extends CamelTestSupport {
//...
}
This works for me:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = TestApplication.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class SomeTestClass {
...
}
Make sure your #ConfigurationProperties annotation is set to the same prefix as whatever you're using in your configuration file (application.config)
If you're using eclipse, its always a good idea to check the projects build resources. (Rclick project->properties->build path)
I was not getting my application.properties file picked up and turned out I simply missed adding it to build resources.
I'm trying to load all properties files form outside jar, below entry in pom works perfect, you can also exclude or include files depends upon requirements.
<build>
<resources>
<resource>
<directory>config</directory>
<includes>FILENAME</includes>
<excludes>FILENAME</excludes>
</resource>
</resources>
</build>

Resources