What is /tmp/jetty-docbase directory used for - spring-boot

I am using SpringBoot and Embedded Jetty.
I see it creates directory /tmp/jetty-docbase...
What is this directory used for? how can I change the root path of it?

It's the document root; the location from which static files will be served by Jetty (rather than by Spring MVC's static resource handling). Spring Boot tries the following locations in order, stopping its search as soon as it finds a match:
An explicitly configured location (ConfigurableEmbeddedServletContainer.setDocumentRoot())
The .war file if running from an executable war
The root directory of an exploded war (identified by the presence of a WEB-INF directory)
./src/main/webapp
./public
./static
$TMP_DIR/jetty-docbase
In your case it's reached 7. This location is used as Jetty needs some location for its document root even if its empty.
If you want to explicitly control the location used for the document root you can configure it by declaring a JettyEmbeddedServletContainerFactory bean:
#Bean
public JettyEmbeddedServletContainerFactory jettyFactory() {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
factory.setDocumentRoot(new File("custom/document/root"));
return factory;
}

Or you can create folder ./public or ./static then springboot will never create temp jetty-docbase folder for you

Related

Give external path in #Value Spring annotation and Resource

In spring boot application how do I give an external windows path using #Value Spring annotation and Resource
The below example works fine that look into resources folder but I want to give the path outside of application like c:\data\sample2.csv
#Value("classPath:/sample2.csv")
private Resource inputResource;
...
#Bean
public FlatFileItemReader<Employee> reader() {
FlatFileItemReader<Employee> itemReader = new FlatFileItemReader<Employee>();
itemReader.setLineMapper(lineMapper());
itemReader.setLinesToSkip(1);
itemReader.setResource(inputResource);
and if I want to get the value from properties file in annotaion, whats the format to put the path in windows?
i tried these, none of them worked:
in code
#Value("${inputfile}")
in properties file:
inputfile="C:\Users\termine\dev\sample2.csv"
inputfile="\\C:\\Users\\termine\\dev\\sample2.csv"
inputfile="C:/Users/termine/dev/sample2.csv"
inputfile="file:\\C:\Users\termine\dev\sample2.csv"
inputfile="file://C://Users//termine///dev//sample2.csv"
When you use classpath spring will try to search with the classpath even if you provide the outside file path.
so instead of using classpath: you can use file:
Ex.
#Value("file:/sample2.csv") //provide full file path if any
Use the key spring.config.location in properties to set the config location. Spring-boot will by default load properties from the locations, with precedence like below :
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
and apart from this when you start the jar or in application.properties you can provide the location of the config file like :
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
You can serve static files from the local disk, by making the resource(s) "sample2.csv" as a static resource. An easy way to do this is by adding spring.resources.static-locations configuration to your applicaiton.properties file. Example:
spring.resources.static-locations=file:///C:/Temp/whatever/path/sample2.csv",classpath:/static-files, classpath:/more-static-resource
When I did this in one of the projects, I was able to access the file form the browser using localhost:8080/sample2.csv.

giving Freemarker resource folder in deployed application for spring boot

I'm trying to give resource folder for Freemarker template below is my bean config
Configuration freeMarkerConfig() throws IOException {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);
cfg.setDirectoryForTemplateLoading(new ClassPathResource("ftl").getFile());
return cfg;
}
and I have ftl folder in the resources folder
-- java
-- resources
-- ftl
-- template.ftl
while deploying it works fine in my local machine but fails in my docker container with exception
java.io.FileNotFoundException: class path resource [ftl] cannot be resolved to absolute file
path because it does not reside in the file system: jar:file:!/BOOT-INF/classes!/ftl
I need to keep ftl in the resources folder and give the directory path to configuration. I don't know how to debug further.
Property spring.freemarker.template-loader-path is available.
spring.freemarker.template-loader-path=classpath:/ftl/
Or, use setTemplateLoaderPath("classpath:/ftl/") instead of setDirectoryForTemplateLoading().
I found the issue after repeated searching. Issue is because of this
Classpath resource not found when running as jar

Spring boot on Tomcat with external configuration

I can't find an answer to this question on stackoverflow hence im asking here so I could get some ideas.
I have a Spring Boot application that I have deployed as a war package on Tomcat 8. I followed this guide Create a deployable war file which seems to work just fine.
However the issue I am currently having is being able to externalize the configuration so I can manage the configuration as puppet templates.
In the project what I have is,
src/main/resources
-- config/application.yml
-- config/application.dev.yml
-- config/application.prod.yml
-- logback-spring.yml
So how can I possibly load config/application.dev.yml and config/application.prod.yml externally and still keep config/application.yml ? (contains default properties including spring.application.name)
I have read that the configuration is load in this order,
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
Hence I tried to load the configuration files from /opt/apache-tomcat/lib to no avail.
What worked so far
Loading via export CATALINA_OPTS="-Dspring.config.location=/opt/apache-tomcat/lib/application.dev.yml"
however what I would like to know is,
Find out why loading via /opt/apache-tomcat/lib classpath doesn't work.
And is there a better method to achieve this ?
You are correct about load order. According to Spring boot documentation
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
[Note]
You can also use YAML ('.yml') files as an alternative to '.properties'.
This means that if you place your application.yml file to /opt/apache-tomcat/lib or /opt/apache-tomcat/lib/config it will get loaded.
Find out why loading via /opt/apache-tomcat/lib classpath doesn't work.
However, if you place application.dev.yml to that path, it will not be loaded because application.dev.yml is not filename Spring is looking for. If you want Spring to read that file as well, you need to give it as option
--spring.config.name=application.dev or -Dspring.config.name=application.dev.
But I do not suggest this method.
And is there a better method to achieve this ?
Yes. Use Spring profile-specific properties. You can rename your files from application.dev.yml to application-dev.yml, and give -Dspring.profiles.active=dev option. Spring will read both application-dev.yml and application.yml files, and profile specific configuration will overwrite default configuration.
I would suggest adding -Dspring.profiles.active=dev (or prod) to CATALINA_OPTS on each corresponding server/tomcat instance.
I have finally simplified solution for reading custom properties from external location i.e outside of the spring boot project. Please refer to below steps.
Note: This Solution created and executed windows.Few commands and folders naming convention may vary if you are deploying application on other operating system like Linux..etc.
1. Create a folder in suitable drive.
eg: D:/boot-ext-config
2. Create a .properties file in above created folder with relevant property key/values and name it as you wish.I created dev.properties for testing purpose.
eg :D:/boot-ext-config/dev.properties
sample values:
dev.hostname=www.example.com
3. Create a java class in your application as below
------------------------------------------------------
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
#PropertySource("classpath:dev.properties")
#ConfigurationProperties("dev")
public class ConfigProperties {
private String hostname;
//setters and getters
}
--------------------------------------------
4. Add #EnableConfigurationProperties(ConfigProperties.class) to SpringBootApplication as below
--------------------------------------------
#SpringBootApplication
#EnableConfigurationProperties(ConfigProperties.class)
public class RestClientApplication {
public static void main(String[] args) {
SpringApplication.run(RestClientApplication.class, args);
}
}
---------------------------------------------------------
5. In Controller classes we can inject the instance using #Autowired and fetch properties
#Autowired
private ConfigProperties configProperties;
and access properties using getter method
System.out.println("**********hostName******+configProperties.getHostName());
Build your spring boot maven project and run the below command to start application.
-> set SPRING_CONFIG_LOCATION=<path to your properties file>
->java -jar app-name.jar

Spring configuration error WEB-INF/servlet-context.xml FileNotFoundException

I have a very simple spring test app. But I get exception even though everything seems to be on order. I might be missing something. Please check the pic to see the project structure and web.xml file contains as well as exception:-
efinitionStoreException: IOException parsing XML document from class path resource [WEB-INF/servlet-context.xml]; nested exception is java.io.FileNotFoundException: class path resource [WEB-INF/servlet-context.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
There are two kinds of resources in a servlet environment:
servlet resources - files uner the root of the web application (loaded via ServletContext)
classpath resources - resources on web application's classpath (loaded via ClassLoader)
When Spring is supposed to load its configuration it needs to know which mechanism to use.
classpath:foo/bar.xml - will load as classpath resource
checking WEB-INF/classes, contents of WEB-INF/lib/*.jar and other shared servlet container's classpath locations
when using maven and its project structure, all files from src/main/resources will be placed on classpath
foo/bar.xml - will load as servlet resource
when using maven and its project structure the src/main/webapp folder is the root of your application
TL;DR As I wrote in the comment, either remove classpath: prefix when referencing XML file or move your XML file to src/main/resources and remove the WEB-INF part.

how to give classpath for a property file using spring

Resource resource = new ClassPathResource("classpath:src/main/resources/template/datafields.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
Your problem is that your file is actually not in the application classpath. Looking at your folder paths I am assuming that you have a maven project structure and your properties file is present within resources directory. When your project is compiled, everything inside the resources directory is at the root of the classpath along with your compiled java classes. So you should instead use
Resource resource = new ClassPathResource("template/datafields.properties");
Classpath resource loads resources from the application classpath, so you need to be aware what all directories/jar files are in your classpath and their directory structure to successfully load resources.

Resources