Spring Boot -Dspring.config.location vs --spring.config.location - spring-boot

What's difference between -Dspring.config.location and --spring.config.location for running Spring Boot in command line?
I saw more than one tutorials and stackoverflow answers running command in this way:
java -jar test.jar --spring.config.location=classpath:test/application.properties
However, no matter how I tried, I failed to load the properties file whereas another way succeeded:
java -jar -Dspring.config.location=classpath:test/application.properties test.jar
I am confused with these two settings.
My project is using:
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
...
</plugin>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.0.0</version>
</dependency>
The way I tested:
#SpringBootApplication
public class Test implements CommandLineRunner {
#Autowired
private ConfigurableApplicationContext context;
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Test.class);
}
#Override
public void run(String... args) throws Exception {
System.out.println(context.getId());
}
}
The first way output is "application". The second way can read my value from my properties file. There are no any errors for both.
Thanks.

Related

Spring Boot/Tomcat, "Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean"

I know there are others questions on this, and I have checked them, but none solves my issue.
Very simple POM, ready:ing my app for use with an embedded web server, simply so I can start it up...
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Very easy Boot class:
#SpringBootApplication
#RestController
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringApplication.class, args);
}
#RequestMapping(value = "/")
public String hello() {
return "Hello World from Tomcat";
}
}
Tried:
Extend the SpringBootServletInitializer class.
Update spring-boot-starter-parent to the latest (2.1.3).
Setting spring.profiles.active=default in application.properties.
Manually inject TomcatWebServerFactory (ugh...) in #Configuration
class.
Run mvn dependency:purge-local-repository and removed /repository dir
from my .m2 dir, fetching all again with mvn clean install -U.
ETC... I do not see why it is not working, I though Spring Boot was supposed to be easy.
Unable to start ServletWebServerApplicationContext due to missing
ServletWebServerFactory bean.
First argument for SpringApplication.run() is expected to be the primary configuration class of your application. In your case it is SpringBootApp.class and not SpringApplication.class. Following would be the correct configuration for your Spring Boot application.
public static void main(String[] args)
{
SpringApplication.run(SpringBootApp.class, args);
}

java.lang.IllegalArgumentException: Sources must not be empty

What is the problem? It was working as well while I updated Ubuntu's software
Main.class
package okt.springbootstarter.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CourseApiApp {
public static void main(String[] args) {
SpringApplication.run(CourseApiApp.class, args);
}
}
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
I don't know where is the problem?
I was facing the same issue.
Try this out, it looks like you are running a wrong class file.
Go to Java file which contains #SpringBootApplication annotation.
e.g (default content):
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
I fix it.
>echo $HOSTNAME
xyz
>sudo gedit /etc/hosts
and
127.0.0.1 localhost
changed
127.0.0.1 xyz
it fixed it.
Change this import :
<artifactId>spring-boot-starter-parent</artifactId>
to this :
<artifactId>spring-boot-starter</artifactId>
And after clean and re build maven

spring boot actuator for standalone spring application

I am trying to learn spring boot actuator. I have a simple basic application which runs via main method. It has not tomcat or anything. It has just one class as below
public class StartUp {
public static void main(String... args) throws InterruptedException {
ConfigurableApplicationContext ctx = SpringApplication.run(StartUp.class,
args);
StartUp mainObj = ctx.getBean(StartUp.class);
mainObj.init();
System.out.println("Application exited");
}
public void init() throws InterruptedException {
System.out.println("inside init method");
Thread.sleep(10 * 60 * 1000);
System.out.println("outside init method");
}
}
I have configured spring actuator as below in pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- [3] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I was trying to view the applications health and info, i have configured the below in application.properties
management.port=8091
management.address=127.0.0.1
management.security.enabled=false
endpoints.shutdown.enabled=true
info.app.name=Startup Dashboard
info.app.version=2.0-ALPHA
logging.file=dashboard.log
while trying the url : http://localhost:8091/info
it never gets resolved.
Is it not possible to configure actuator for standalone applications ?
Your application is not a Spring Boot App yet.
One has to use the #SpringBootApplication at the minimum to convert an app into one.
#SpringBootApplication
public class BootadminMsAlphaApplication {
public static void main(String[] args) {
SpringApplication.run(BootadminMsAlphaApplication.class, args);
}
}
is one such simplest example.
Without this, the spring-boot dependency in your classpath have not been asked to do its magical things to make your application smart. The all-in-one annotation brings spring-boot's auto-configuration into play, that configures a lot of good stuff for the app, including Actuators (if in classpath).
It looks like your application isn't a Spring Boot application. It needs to be.

#Configuration inside jar not getting loaded

We #Configuration file inside our project and we are adding one "xyz.jar" in class-path as maven dependency having another #Configuration file.
We are using one autowired bean from "xyz.jar" and when we run our project getting following error for this bean.
"No qualifying bean of type"
We are using Spring-boot, spring-amqp and maven.
We have tried one solution to this by adding following lines to our configuration class
#AutoConfigurationPackage
#Import(value = XYZConfiguration.class) //another #Configuration class from jar
This is working but not working when we run this jar on docker container.
Could you please help.
//Spring boot application class
#SpringBootApplication
public class Application implements CommandLineRunner
{
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args)
{
logger.debug(" Application starting ....");
SpringApplication.run(VApplication.class, args);
}
#Override
public void run(String... arg0)
{
logger.debug("Application is running....");
}
}
// Configuration class
#Configuration
#AutoConfigurationPackage
#Import(value = XYZConfiguration.class)
public class VRMQConfig
{
//Bean Configuration
}
Docker File:
FROM anapsix/alpine-java
MAINTAINER MyService
COPY myservice.jar /home/myservice.jar
CMD ["java","-jar","/home/myservice.jar
POM file :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>

ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean

Trying to setup a simple web application scheduler. So here is my configuration:
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>scheduler</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.1.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<start-class>hello.Application</start-class>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>hello.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
My classes look like below
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(ScheduledTasks.class);
}
public void onStartup(ServletContext arg0) throws ServletException {
SpringApplication.run(ScheduledTasks.class);
}
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(8081);
factory.setSessionTimeout(50, TimeUnit.MINUTES);
return factory;
}
}
#EnableScheduling
public class ScheduledTasks {
#Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
But when i try to start the container i see the exception
ERROR 2592 --- [ost-startStop-1] o.s.boot.SpringApplication : Application startup failed
...
...
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:174)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:147)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:121)
... 20 more
I tried to follow Spring Boot Testing: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean but in vain.
Kindly suggest, thanks
You are only running ScheduledTasks:
SpringApplication.run(ScheduledTasks.class);
when you should run:
SpringApplication.run(Application.class);
Running ScheduledTasks means that Spring Boot doesn't know about the configuration in Application. Crucially, it means that it doesn't see #EnableAutoConfiguration which is what switches on auto-configuration and, because you have Tomcat on the classpath, creates the embedded Tomcat instance.
I would fix this by moving the #EnableScheduling annotation from ScheduledTasks to Application, running Application.class rather than ScheduledTasks.class, and annotating ScheduledTasks with #Component:
Application.class:
#Configuration
#EnableAutoConfiguration
#ComponentScan
#EnableScheduling
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
// …
}
ScheduledTasks.class:
#Component
public class ScheduledTasks {
#Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
Moving #EnableScheduling means that its on a configuration class, where it belongs. Running Application.class means that Spring Boot sees all of its configuration, including enabling component scanning and enabling auto-configuration. Annotating ScheduledTasks with #Component means that it's found by component scanning and its #Scheduled method is detected.
This should get things up and running. I would also correct your pom so that you're not using a mixture of versions of Spring Boot (you have 1.1.6 and 1.1.7 in there at the moment) and get rid of your EmbeddedServletContainerFactory bean in favour of configuring the port and session timeout using application.properties in src/main/resources instead:
application.properties:
server.port = 8081
server.session-timeout = 3000
besides what #Andy Wilkinson pointed out which is true in the OP's case but not in mine
I saw that my spring-boot-starter-tomcat was with
<scope>provided</scope>
( as i was adding a servlet initializer to run it on wildfly) i commented out that bit and removed provided from spring-boot-starter-tomcat dependency and it started working. Adding here just in case some one else has the same issue
My one got fixed using this dependency :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>

Resources