Read Spring properties in React - spring

I have a Spring/React webapp. In my application.properties file I defined spring.data.rest.base-path = /apiso when running the app locally, everything is accessible on localhost:8080/api. If I deploy this to my tomcat, the all the stuff goes to localhost:8080/warname/api.
I can easily define my warname in my properties file. And in React,
path: '/api/myStuff'
I can access my data.
Also I can change that to
path: '/warname/api/myStuff'
and everything will work. But to make things easier, it would be better to read the warname from my pom.xml so I wouldn't have to change every path in my .js. How to get that done?

If you have a directory named ROOT in your Tomcat directory, you have to remove it and change the name of your war to ROOT.war so that when Tomcat explodes the war it will be the main root project.

Related

Spring Boot App log file is being saved to the parent directory instead of project directory

I created an Empty Project in Intellij IDEA and added my Spring Boot projects via Import Module. Now I'm incorporating logging to my apps. I added the following configuration to one of my apps (API Gateway)
logging:
file:
name: api-gateway.log
I am expecting that the log file will be created/stored at the app's root directory.
However, the log file was saved in the main project's root directory.
I tried adding path but log file is not generating.
logging:
file:
name: api-gateway.log
path: spring-cloud-api-gateway
I would like to know if this is the default behavior when an app is imported to an empty project.
I found the problem and sharing here for reference. Edit your Run/Debug Configurations and specify the Working directory. Leaving it blank defaults the the Parent Project root directory.

spring boot loading property file from custom folder

I need to load a property file from src/main/resources/config folder. The loading part is written in a common dependency project where we dont have any control. We are just passing the file name expressed through a dependency. The code snippet in the dependent jar is like below, the standard resource loading.
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(propertyFileName);
Spring will always look for recources under recources folder directly, in this case its unable to load the file as its in the custom folder and its not under classpath.
How do we explicitly set the custom folder as additional classpath folder?
With maven we could do something like below which works fine. Is there any OOTB way to achieve this with annotation in spring boot?
`<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/resources/config</directory>
</resource>
</resources>`
Updated
`// This works if config.properties is directly under resource folder
// What if config.properties is under resources/config folder.
// Dont say to pass argument as /config/config.properties, there are some other limitations.
// So in that case with the same approach, config should come under classpath, so that the below
// method will work always when the property name is passed.
// As mentioned earlier, we can use maven resource settings to achieve this.
// The question here is, is there any way to explicitely advise spring to load property from this folder.
// I have seen something like loader.path config, not sure that helps!
InputStream stream = SpringBootStarter.class.getResourceAsStream("/config.properties");`
Before answering, when you say: Spring will always look for recources under recources folder directly, in this case its unable to load the file as its in the custom folder and its not under classpath., this is not correct.
Spring can look anywhere on your system. Here is how you can load different properties file with Spring and Spring boot:
#PropertySource("classpath:config/common.properties") => Will look under the class path for a file located under the config folder, at the root of your classpath.
#PropertySource("file:/config/common.properties") => Will look for the file common.properties at the root of your filesystem, here under /config/common.properties.
Now, there is the question of "what is the classpath", it seems like it is worth more explanation.
The classpath is for the JVM what the filesystem is for your OS. When you execute some java code (.jar file for instance), the JVM stores all the files you specify. You can specify files when executing java -classpath /a/shared/folder,/a/dependency/app.jar,myApp.jar MainClass. (See this for some others ways: https://javarevisited.blogspot.com/2012/10/5-ways-to-add-multiple-jar-to-classpath-java.html).
Quite often, what happens for developers (before we use Spring) was this:
We develop our application, and use maven for managing the dependencies
We execute our app with the IDE, everything works just as fine, life is wonderful
We are ready to go live (in production). We generate the famous myApp.jar and try executing the application java -jar myApp.jar and... Nothing works. You have issues with java (I assume you setup the main-class in the Manifest...) and you get something like Caused by: java.lang.ClassNotFoundException: my.dependency.OtherClass...
Finally, you realize life is hard and you are not ready to go live right now. You need to have something you can execute easily.
One possible solution to this, to avoid having classpath issues is to put everything in your JAR (called in spring-boot the FAT jar) and you use java -jar myApp.jar and it is working fine.
By default, when you generate a maven project, automatically you have some folders included like:
src/main/java => your java files and packages
src/main/resources => your config files (like .properties)
src/test/java => Your java test files
src/test/resources => the resources handy for your tests
When you generate your jar (more or less every configuration you added to your maven project, but let's say it is okay), what happens is the compiler takes all the folders and files under src/main/java and src/main/resources and put them at the root of your jar. (Don't hesitate to have a look inside your jar files. This is just a Zip, you can open it, browse it, and see for yourself).
With that said, when you say How do we explicitly set the custom folder as additional classpath folder?, and you talk about a custom folder located under src/main/resources, then when you generate your Jar, the custom folder will be in jar, and therefor, in your classpath.
If you still have troubles, this actions will help you:
Unzip your jar files and check what is inside. If you don't see any config/ folder in it, maybe your Jar generation is wrong
Try using #PropertySource(...) to load properties file, in your classpath and in your filesystem, to see how it works and what you achieve
Have also a look to this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
Don't hesitate to migrate more and more of your old code to Spring-boot, will be a lot easier for you.

Deploy a embedded Jetty&Jersey war to jetty9,only can see static file?

I cteate a jetty&jersey embedded project with IDEA and Maven,I put it in Github https://github.com/Mengqi777/JettyProject. Run JettyServerStart.java start the server, in the browser address bar enter localhost:8080/dynamic, show OK, enter localhost:8080/static, show static resource file
Now I package it to a war file,and put it in jetty webapps directory. But only can see static file in brower with enter localhost:8080/static.404 Not Found Error when in brower with enter localhost:8080/dynamic
What happend?
What should I do to package this project into a war file or jar file and run it in jetty successfully?
You are doing things in your embedded-jetty usage in JettyServerStart.java that you do not declare/configure in your webapp or war file.
It's a maven project, but not declared as a webapp or war project (in the pom.xml)
Its doesn't have its WEB-INF in the right place (maven directory structure wise), which means your built war file is invalid.
The dependencies are not declared correctly for a webapp or war project (you cannot include jetty-server in a war file)
Your badly located WEB-INF/web.xml does not perform the same configuration steps as your JettyServerStart.java
You don't specify how you created your ${jetty.base} directory to support this war file?
You didn't specify what version of jetty-distribution or jetty-home you downloaded, or are attempting to work with.
The statement "and put it in jetty webapps directory" is unclear, which one? (using jetty-distribution/webapps is invalid and will cause many errors and warnings if you attempt to use it for your own webapps, there's no jetty-home/webapps, and you didn't identify your jetty-base configuration)
The way your project is declared right now, even if manually assembled, skipping maven entirely, you have no servlets, no filters, no listeners, no intializers, only a servlet spec mandated DefaultServlet on url-pattern / giving you static content. That's why accessing http://localhost:8080/static/ works, but nothing else.

Springboot application cannot find application.yml from external folder (#PropertySource)

I am trying to write a spring boot app (for tomcat), which has an application.yml file for configuration.
My goal is to search for this yml file FIRST from the resources, and if it is not there, then SECONDLY from the tomcat's conf folder.
My code, which is not working:
#SpringBootApplication
#ComponentScan(basePackages = "com.my.app")
#EnableConfigurationProperties
#PropertySource(ignoreResourceNotFound=true,value={"classpath:application.yml","file:${catalina.base}/conf/application.yml"})
public class MyApplication extends SpringBootServletInitializer {
...
}
I want this, because if I work on my Eclipse, and want to use Tomcat server from Eclipse. In this case I want to use the resources folder. But if I build the war then I skip the yml file from it with the maven war plugin, and deploy it manually to Tomcat, I want to use the tomcat's folder.
if I leave the yml file on the resources folder of the project, it works
if I delete the yml file from the resources, and place to the ${catalina.base}/conf folder (which is the embedded tomcat for eclipse, I know it), it doesn't work
if I delete the #PropertySource annotation, and leave the yml file in resources, it works
So my app works only if the yml file on the resources folder, even if I add or remove the #PropertySource annotation.
How should I set to search for the resources folder for first time, and if there is no yml file, then search for the second option, which is the tomcat folder?

serving files from a spring boot war file

I've followed the guide here for turning a "hello, world" level Spring Boot app to a war file. I can run this war like a jar and it will return the simple template.
What I don't understand is why I can't access a main.css file I've created. I've placed it in the resources directory under "static/css/main.css" and according to the docs here Spring Boot will automatically server files under "resources", "static", "public", and "META-INF/resources". However, when I build my war file and run it I can't query those files in the browser (like http://localhost:8080/static/css/main.css). Have a missed a step? If I peek into the created war file I see the "static" directory in "WEBINF/classes" right beside the "templates" directory and the directory holding my application.
Files in src/main/resources/static are served from / so you don't need static in the path. You CSS file should be available from http://localhost:8080/css/main.css

Resources