Not able to load external properties files with springboot in weblogic - spring-boot

I am trying to load the external properties file in spring boot with tomcat it is working as expected while putting it in lib folder but I am not able to load with weblogic server though I put application.properties file in lib folder.
Code snippet :
public class ApplicationFilesInitializer extends SpringBootServletInitializer implements WebApplicationInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class).properties(getProperties());
}
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.location","classpath:{appname}-application.properties");
return props;
}
}

So Below is the link to load external properties file.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
The code which you share will work in tomcat as under lib folder is the actual classpath so it will load while server start up, but it will not work with weblogic as weblogic classpath is user domain folder and not the lib folder.
Can you try to put application.properties file in user domain folder and it should work.
Find your user domain path in weblogic and put app. files there.
Below is the code you can find your weblogic user domain path/classpath :
String appDomianPath= System.getProperty("user.dir");
System.out.println(appDomianPath);

Related

Spring Boot App as .war is running, but endpoint is not working

I built a Spring Boot Rest API and want it to run in a Tomcat container on a Linux server.
I have a server on digitalocean running on Ubuntu 20.4
I installed tomcat as described in this article and it is running
I build a very small Spring Boot Application with only one endpoint, which I want to build and deploy on the tomcat server. You can see the build.gradle file here in my github repository: spring-boot-example
Here are some Code Snippets:
#RestController
public class ExampleController {
#GetMapping(value = "/hello-world")
public ResponseEntity<String> helloWorld() {
return ResponseEntity.ok("Hello world");
}
}
#SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ExampleApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class);
}
}
This is basically the whole app
Steps taken:
building the war file with './gradlew war' or './gradlew bootWar' locally on my machine (I tried both, i don't know if it makes any difference, but I had the issue with both of them)
Opening the tomcat manager remotely on http://'host':8080/manager/html
Deploying the .war file manually and waiting until it's deployed:
As you can see, it is up and running:
Now I open the following URL: http://host:8080/spring-boot-example/hello-world, where I expect to see the message Hello world, as defined in the Controller
But all I can see is this
Did I miss something? It says at the end or is not willing to disclose that one exists, do I have to do something with that endpoint to make it available to the public? Or did I upload the app incorrectly?

How to view autoconfigure log output during spring boot server start

How to view autoconfigure log output during spring boot server start
I have created a spring boot application. It uses a shared library (Spring boot jar via maven dependency). Shared library class is loaded via
META-INF/spring.factories
I have mentioned the classes from the library in spring.factories. The job of shared library is to read Vault role id and Vault
secret id value from application.properties and call a REST API and fetch secrets from Vault. After fetching the secret it sets the value again in system property.
for (Map.Entry<String, String> entry : allSecrets.entrySet())
{
System.setProperty(entry.getKey(), entry.getValue());
}
Everything is working as expected. But I am not able to see logs from shared library in my logs.
shared library's package structure is com.myorg.abc. My spring boot package structure is com.myorg.xyz
I tried the following in application properties.
logging.level.root= DEBUG
logging.level.com.myorg.xyz: DEBUG
logging.level.com.myorg.abc: DEBUG
logging.level.org.springframework.boot.autoconfigure.logging=DEBUG
I am able to get logs only from my application but not from shared library. But when I change the shared library Logger.error to System.out, then I am getting the message in my application. How to view shared library's log in my application.
Spring boot initializes logging at least 3 times. The first happens when SpringApplication is loaded. It creates an SLF4J Logger before anything in Spring is accessed. This causes whatever logging implementation you have chosen to initialize. By default, it will use the logging configuration in the Spring jar. With Log4j 2 you can override this by setting log4j.configurationFile to the location of your desired configuration either as a system property or in a log4j.component.properties file.
Everything Spring does will be logged using this configuration until it initializes the logging configuration again, which is controlled by bootstrap.yml. Finally, your application's logging configuration is initialized which is configured either from application.yml or again from bootstrap.yml.
I replaced org.springframework.boot.env.EnvironmentPostProcessor with org.springframework.context.ApplicationListener in Spring.factories and it fixed the issue. I was able to get logs from shared library in invoking application.
Spring.factories
org.springframework.context.ApplicationListener=com.mypackage.MyClassName
MyClassName.java
public class MyClassName implements ApplicationListener<ApplicationPreparedEvent>
{
private static final Logger LOGGER = LoggerFactory.getLogger(MyClassName.class);
#Override
public void onApplicationEvent(ApplicationPreparedEvent applicationPreparedEvent)
{
ConfigurableEnvironment configurableEnvironment = applicationPreparedEvent.getApplicationContext()
.getEnvironment();
String roleId = configurableEnvironment.getProperty(Constants.VAULT_ROLE_ID_LITERAL);
String secretId = configurableEnvironment.getProperty(Constants.VAULT_SECRET_ID_LITERAL);
...
Optional<String> errorMessage = ServiceUtil.validateSystemProperty(roleId, secretId);
if (!errorMessage.isPresent())
{
Map<String, String> secret = ServiceUtil.getSecret(roleId, secretId);
for (Map.Entry<String, String> entry : secret.entrySet())
{
System.setProperty(entry.getKey(), entry.getValue());
}
LOGGER.info("Successfully populated secrets from Vault in system property");
}
else
{
LOGGER.error("Failed to populate secrets from Vault in system property. Error:{}", errorMessage.get());
}
}
}
application.properties
logging.level.com.myorg.abc: DEBUG

Unable to access the html file in template folder of spring boot application

html files are placed under resources/templates/login.html directory of spring boot application(show in the screenshot), deployed it in the weblogic server and when I try to access the login.html with the below URL, it gives The webpage cannot be found message
http://localhost:7001/demo/login.html
below is the screenshot
In one of the post I found the below code snippet and tried, but it didn't work
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
I am not getting what mistake I did, Could some one help me regarding this ...?
Spring Boot by default serves all content found under /static, /public, /resources or /META-INF/resources, see docs. So all content in your static folder should be served well (check that). But the templates folder is not a sub-folder of the static, so it will not be served. If I get you right, the templates is not supposed to be part of the URL path, right? So you could either move your login.html to the static folder, or you could add the templates folder to the classpath resource locations. Either programmatically (as you did for the other locations), or by setting the corresponding property:
spring.resources.static-locations=classpath:/templates/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/

How to change the way Spring Boot serves static files?

After using JHipster on a couple of new projects recently (Highly recommended ! Amazing work !), I am trying to back-port some of the concepts into an older webapp, essentially migrating it to Spring Boot and Angular.
In Spring Boot, the default location for static web resources (HTML, JS, CSS, etc.) is in a directory called public, static or resources located at the root of the classpath. Any of these directories will be picked up by spring boot and files in them will be accessible via HTTP.
In JHipster the web files are in the src/main/webapp directory. Which is the directory used by default in a classic Maven WAR project.
I like this better because :
it more clearly separates the static web stuff from the classpath resources used by the Java code
the nesting is less deep (we already have enough levels of directories nesting with Maven as it is!).
But if I just create webapp directory in my project and put my HTML files in it, they are not available via HTTP, and the build process creates the WEB-INF directory structure in it. I don't want that, and in JHipster this is not the case.
How can I configure Spring Boot to behave like it does in JHipster ?
For those not familiar with JHipster : How can I instruct Spring Boot to serve static files from a different folder, no included in the classpath ?
You can try following configuration. The idea should be pretty straight forward. It does register artifacts in assets directory.
public class AppMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Including all static resources.
registry.addResourceHandler("/assets/**",
"/css/**",
"/img/**",
"/js/**"
).addResourceLocations("/assets/",
"/css/",
"/img/",
"/js/"
).resourceChain(true)
.addResolver(new PathResourceResolver());
super.addResourceHandlers(registry);
}
}
you can add following code in application.propertise:
spring.resources.static-locations=classpath:/webapp/
and following code in application.yaml:
resources:
static-locations: classpath:/webapp/
I recently had the same issue and simply did a text search for "robots.txt" within my jHipster generated files.
I added my new file to the assets array in angular.json and put my new file in the same location as robots.txt, which as stated earlier is webapps.

Serving static contents in Spring Boot

I am developing a new poc for web application from Spring Boot. The packaging type of my application in war. In this all i want is to display some contents on a jsp. For that i have created a small jsp, and requierd css/images/js files i have put in resources/static folder. So my static folder contains css/images/js folders. I've added following code in my configuration file. My configuration extends from WebMvcConfigurerAdapter
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String[] pathPatterns = {"/components/**", "/images/**", "/scripts/**", "/styles/**"};
String[] resourceLocations = {"classpath:/static/components/", "classpath:/static/images/", "classpath:/static/scripts/, classpath:/static/styles/"};
registry.addResourceHandler(pathPatterns).addResourceLocations(resourceLocations);
}
However, my jsp does not get the reference of these file.
JSP Code
How to solve above problem..
Second concern, as per the spring boot reference documentation, it serves the static content which are located in static folder. that means i should be able to access files from my static folder directly in below way
http://localhost:8080/styles/main.css
But this is also not working
Third Issue - static contents are served by default servlet ..is this true that Default servlet in enabled by default in Spring Boot application
Please Help
Putting the static resources inside src/main/resources/static folder works for me without any addResourceHandlers configuration. For example, I have a css file at
src/main/resources/static/public/css/styles.css
which I refer from my JSP like this:
<link href="/public/css/styles.css" rel="stylesheet">
You should have put your JSPs inside src/main/webapp/WEB-INF, and set the packaging to war rather than jar, due to the limitations of having JSPs in Spring Boot.

Resources