I have a data project and UI project. Both projects are Spring Boot applications. Both projects have the same root package (com.myorg) with a main class annotated with @SpringBootApplication
.
Data project's main class is:
package com.myorg;
@SpringBootApplication
public class DataApplication {
public static void main(String[] args) {
SpringApplication.run(DataApplication.class, args);
}
}
The UI project's main class is:
package com.myorg;
@SpringBootApplication
public class UiApplication {
public static void main(String[] args) {
SpringApplication.run(UiApplication .class, args);
}
}
The UI project depends on the data project via the following Gradle dependency:
dependencies {
compile('com.myorg:data:1.0')
}
If I run the UI application, it runs without issue. However, if I run an integration test within the UI application such as follows:
package com.myorg
@RunWith(SpringRunner.class)
@SpringBootTest
public class UiIntTest {
@Test
public void contextLoads() {
}
}
The following initialization error occurs:
java.lang.IllegalStateException: Found multiple @SpringBootConfiguration annotated classes
In the data project's main class, if I replace @SpringBootApplication
with
@Configuration
@EnableAutoConfiguration
@ComponentScan({ "com.myorg" })
I get the following initialization error when trying to run its integration tests:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
For example, if I try to run:
package com.myorg
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataIntTest {
@Test
public void contextLoads() {
}
}
How can I properly configure the data and UI projects?
No you can have only one application listening on a specific port at a time.
@SpringBootApplication Annotation Features not Mandatory.
It's not mandatory to put @SpringBootApplication to create a Spring Boot application, you can still use @Configuration and @EnableAutoConfiguration individually as shown in the example given in the next point.
You need to specify which Spring Boot Main class to use along with @SpringBootTest
:
@SpringBootTest(classes = YourUiSpringBootApp.class)
You shouldn't have two SpringApplication annotations in the same package.
Package one.
twoapps.one;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackageClasses = {One.class})
@EnableAutoConfiguration
public class One extends SpringApplication {
}
Package two.
twoapps.two;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackageClasses = {Two.class})
@EnableAutoConfiguration
public class Two extends SpringApplication {
}
Root package and launcher
package twoapps;
import org.springframework.boot.SpringApplication;
import twoapps.one.One;
import twoapps.two.Two;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Application {
public static void main(String[] args) throws Exception {
new Thread(() -> SpringApplication.run(One.class, args(args, "--spring.profiles.active=one"))).start();
new Thread(() -> SpringApplication.run(Two.class, args(args, "--spring.profiles.active=two"))).start();
}
private static String[] args(String[] args, String s) {
List<String> collect = Arrays.stream(args).collect(Collectors.toList());
collect.add(s);
String[] strings = collect.toArray(new String[]{});
return strings;
}
}
This is a terrible idea. please don't do it. It is much better to have two different projects and a common project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With