When I removed REST part from my basic Spring Boot application:
#Configuration
#EnableAutoConfiguration(exclude = {EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class}) // Do not start Tomcat yet
#ComponentScan
public class ViewsAggregatorApplication {
public static void main(String[] args) throws InterruptedException, IllegalAccessException {
SpringApplication.run( MyApplication.class, args);
}
}
I have found out that my application quits immediately. I however intent to have inside AMQP listener and sender, so I'd like it to stay running. What is the best way to do so?
Related
my project's configure is:
spring-cloud-dependencies is Dalston.RELEASE,
springboot is 1.5.8.RELEASE;
the dependencies like:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
the code like this:
#SpringBootApplication
#EnableDiscoveryClient
#RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#GetMapping("/test/getId")
public String getId(#RequestParam("id") String id){
return "return the id is:"+id;
}
}
consul is running(consul.exe agent -dev),when running the project, the consul show the log:
2018/08/09 15:49:59 [WARN] agent: Check "service:mdp-service-release-flatform-provider-cache-redis-dev-dev-9098" is now critical
I cannot consume the provider, what is wrong?
Issue : When running integration tests from maven (mvn verify) the spring application context is not initialized properly, it doesn't take in consideration my custom ApplicationContextInitializer class.
Test Class :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {MainApplication.class}, initializers = CustomContextInitializer.class)
#WebIntegrationTest
public class ApplicationIT {
// Running a SOAPUI suite as a JUnit Test
#Test
public void TestGateway() throws Exception {
SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
runner.setProjectFile("../gateway/src/test/resources/soapui/gateway-soapui.xml");
runner.run();
}
}
MainApplication class :
#Configuration
#ComponentScan(basePackages = {
// different packages here (not relevant)
})
#EnableAutoConfiguration
public class MainApplication {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(MainApplication.class)
.initializers(new CustomContextInitializer())
.run(args);
}
}
CustomContextInitiliazer class (for adding custom .properties files to the spring environment application context) :
public class CustomContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment env = applicationContext.getEnvironment();
try {
Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath*:/*.properties");
for (Resource re : res) {
env.getPropertySources().addFirst(new ResourcePropertySource(re));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Results :
1) Everything works on when I start and run the application (either from IDE or by invoking mvn exec).
2) Integration tests run ok when started from IDE.
3) Integration tests throw error when invoked via maven verify because the custom properties files are not loaded into spring context environment. The result is the same as if I wouldn't have written initializers = CustomContextInitializer.class in the test class and tried to run the tests from IDE.
I think your code is correct, but your .properties files may be at the wrong place. Make sure they are under <project>/src/main/resources or that you have configured a custom resource folder in maven. If they reside under <project>/src/main/java they will not be part of the classpath as far as maven is concerned.
Do I configure properties like the connectionTimeout in the application.properties file or is the somewhere else to do it? I can't figure this out from Google.
Tomcat properties list
I found this Spring-Boot example, but it does not include a connectionTimeout property and when I set server.tomcat.connectionTimeout=60000 in my application.properties file I get an error.
Spring Boot 1.4 and later
As of Spring Boot 1.4 you can use the property server.connection-timeout. See Spring Boot's common application properties.
Spring Boot 1.3 and earlier
Provide a customized EmbeddedServletContainerFactory bean:
#Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(connector ->
((AbstractProtocol) connector.getProtocolHandler()).setConnectionTimeout(10000));
// configure some more properties
return factory;
}
If you are not using Java 8 or don't want to use Lambda Expressions, add the TomcatConnectorCustomizer like this:
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
#Override
public void customize(Connector connector) {
((AbstractProtocol) connector.getProtocolHandler()).setConnectionTimeout(10000);
}
});
The setConnectionTimeout() method expects the timeout in milliseconds (see connectionTimeout in Apache Tomcat 8 Configuration Reference).
I prefer set of system properties before the server start:
/**
* Start SpringBoot server
*/
#SpringBootApplication(scanBasePackages= {"com.your.conf.package"})
//#ComponentScan(basePackages = "com.your.conf.package")
public class Application {
public static void main(String[] args) throws Exception {
System.setProperty("server.port","8132"));
System.setProperty("server.tomcat.max-threads","200");
System.setProperty("server.connection-timeout","60000");
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
After spring boot 2.x and later,
the implement method of the embeding tomcat has been changed.
refer to the code below.
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
import lombok.extern.slf4j.Slf4j;
#Slf4j
#Configuration
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
#Autowired
private ContainerProperties containerProperties;
#Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(connector -> {
AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
protocol.setMaxKeepAliveRequests(10);
log.info("####################################################################################");
log.info("#");
log.info("# TomcatCustomizer");
log.info("#");
log.info("# custom maxKeepAliveRequests {}", protocol.getMaxKeepAliveRequests());
log.info("# origin keepalive timeout: {} ms", protocol.getKeepAliveTimeout());
log.info("# keepalive timeout: {} ms", protocol.getKeepAliveTimeout());
log.info("# connection timeout: {} ms", protocol.getConnectionTimeout());
log.info("# max connections: {}", protocol.getMaxConnections());
log.info("#");
log.info(
"####################################################################################");
});
}
}
It's actually supposed to be server.connection-timeout in your application.properties. Reference, I suggest you bookmark it.
I have a Spring Boot app:
#SpringBootApplication
#EnableAutoConfiguration
public class MySystem extends SpringBootServletInitializer {
public static void main(final String... args) {
SpringApplication.run(MySystem.class, args);
}
}
The project layout is like this:
MyApp/
src/main/java
src/test/java
src/integration-test/java
In src/integration-test/java I have a Spring configuration:
#Configuration
static class BootstrapIntegrationTestConfig {
#Bean
public DataSource h2DataSource() {
...
}
}
Unfortunately, when I start my Spring Boot app the src/integration-test/java folder will also be scanned and the BootstrapIntegrationTestConfig is loaded.
How can I prevent my Spring Boot app from scanning the src/integration-test/java?
I'm working with Eclipse and Gradle and I already tried to exclude test and integration-test from bin, but it didn't work:
import org.gradle.plugins.ide.eclipse.model.SourceFolder
eclipse.classpath.file {
beforeMerged { cp ->
cp.entries.clear()
}
whenMerged { cp ->
cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/integration-test/") }*.output = "integration-test-bin"
cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/test/") }*.output = "test-bin"
}
}
I have a dropwizard project and I have maintained a config.yml file at the ROOT of the project (basically at the same level as pom.xml). Here I have specified the HTTP port to be used as follows:
http:
port:9090
adminPort:9091
I have the following code in my TestService.java file
public class TestService extends Service<TestConfiguration> {
#Override
public void initialize(Bootstrap<TestConfiguration> bootstrap) {
bootstrap.setName("test");
}
#Override
public void run(TestConfiguration config, Environment env) throws Exception {
// initialize some resources here..
}
public static void main(String[] args) throws Exception {
new TestService().run(new String[] { "server" });
}
}
I expect the config.yml file to be used to determine the HTTP port. However the app always seems to start with the default ports 8080 and 8081. Also note that I am running this from eclipse.
Any insights as to what am I doing wrong here ?
Try running your service as follows:
Rewrite your main method into:
public static void main(String[] args) throws Exception {
new TestService().run(args);
}
Then in eclipse go to Run --> Run configurations...., create a new run configuration for your class, go to arguments and add "server path/to/config.yml" in "program arguments". If you put it in the root directory, it would be "server config.yml"
I believe you are not passing the location/name of the .yml file and thus your configurations are not being loaded. Another solution is to just add the location of your config file to the array you're passing into run ;)