Load properties file external to webapp in Jetty - jetty

I have a webapp which I deploy on a Jetty server through jetty runner. I inject properties read through a properties file using Spring. As of now, I have kept the properties file within the webapp itself (in WEB-INF/classes) directory. I want to keep this properties file external to the webapp and then inject them using Spring. Is there any configuration in the jetty.xml file I can do so I can achieve this?

I managed to solve this by adding the properties file as a command line parameter while starting jetty. Something like:
java -Dexternal.properties.file=myfile.properties -jar jetty.jar
In java code, I read it by getting system property and then using FileUtils to get file.
String externalPropertiesFile = System.getProperty("extern.properties.file");
File file = FileUtils.getFile(externalPropertiesFile);

Related

Hadoop s3 configuration file missing

I'm using the Hadoop library to upload files in S3. Because of some metric configuration file is missing I'm getting this exception
MetricsConfig - Could not locate file hadoop-metrics2-s3a-file-system.properties org.apache.commons.configuration2.ex.ConfigurationException:
Could not locate: org.apache.commons.configuration2.io.FileLocator#77f46cee[fileName=hadoop-metrics2-s3a-file-system.properties,basePath=<null>,sourceURL=,encoding=<null>,fileSystem=<null>,locationStrategy=<null>]
My current configurations are
configuration.set("fs.s3a.access.key", "accessKey")
configuration.set("fs.s3a.secret.key", "secretKey")
Where to add this configuration file? What to add to that configuration file?
don't worry about it, it's just an irritating warning. It's only relevant when you have the s3a or abfs connectors running in a long-lived app where the metrics are being collected and fed to some management tooling.
Set the log level to warn in the log4j.properties file in your spark conf dir
log4j.logger.org.apache.hadoop.metrics2=WARN
I just placed an empty file in the classpath and it stopped complaining. Like:
touch /opt/spark/conf/hadoop-metrics2-s3a-file-system.properties

How to use environment variables for Springboot application using a .env file?

I am trying to build a Springboot application which connects to a DB. I would like to use a .env file which has the sensitive content. At the first hand, I am testing by changing the port to 8081.
My .env file has the following content
PORT=8081
My application.properties has the following content
server.port=${PORT}
I have a run time error that PORT cannot be resolved, which is to be expected when I did not know how to feed the .env file to properties.
Could someone point me in the right direction?
PS: I am using the port as an example, if this succeeds I will also set the DB Credentials with the .env file.
UPDATE:
I would prefer using .env file because when the application is deployed using AWS CodePipeline, I can have the environment variables set in the CodeBuild stage where I would be building the jar and eventually a docker image in this stage. Something like this.
EnvironmentVariables:
- Name: PORT
Value: "{resolve:secretsmanager:DBCredentials:SecretString:port}"
The error is Caused by java.lang.IllegalArgumentException: Could not resolve placeholder 'PORT' in value "${PORT}"
I think you have the react approach ! But in spring for using multiple environments, it's better to have a properties file or yaml by environment.
Ps: File name must be named like application-{environment name}.properties and must be in the resources folder.
For dev:
File name : application-dev.properties
server.port=8089
For IT:
File name : application-it.properties
server.port=8090
In the application.properties file, where usually we put some shared properties between all the environments, we can add the propertie : spring.profiles.active = dev // you can put what you want depending on your needs. If you have more than one profile you can separate them by " , ".
For more details you can check spring profiles

Configure unit tests so that log4j configuration is not required

I want to build spring-boot application with external log4j2 configuration. I created project where log4j config is bundled with spring-boot application jar file, but it is stored outside jar file. Application loads configuration file that is defined in application.properties eg. logging.config=file:config/log4j2.xml. The app structure looks like this:
app.jar
config:
->application.properties
->log4j2.xml
App starts correctly and sees both configuration files. However tests can't locate log4j2.xml that is defined in application.properties.
I've created test.properties file as follows:
logging.level.com.mypackage=TRACE
# This sets the global logging level and specifies the appenders
log4j.rootLogger=TRACE, theConsoleAppender
# settings for the console appender
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%d %p %c{10} [%t] %m%n
and annotated my test class with:
#TestPropertySource(locations="classpath:test.properties")
But test runner still looks for file defined in logging.config.
What properties should I override in application.properties file so that log4j2.xml is not required during unit testing?
Thanks for any help.
Best think, I could came up with, was overriding property logging.config to point to log4j configuration contained on classpath and added log4j configuration as test resource.
In my test.properties
logging.config=classpath:log4j2.xml

Uploading files to a bluemix app and pointing to them from configuration files

I am trying to upload files to my bluemix app and I am having problems using and understanding the file system. After I have succesfully uploaded files I want to give their path on my configuration files.
Specifically, I want to upload a jar file to the server and later use it as javaagent.
I have tried approaching this isuue from several directions.
I see that I can create a folder in the liberty_buildpack and place the files inside I can later access it on the compilation-release phases from the tmp folder:
/tmp/buildpacks/ibm-websphere-liberty-buildpack/lib/liberty_buildpack/my_folder
Also I can see that in the file system that I see when building and deploying the app I can copy only to the folder located in:
/app
So I copied the JAR file to the app file and set it as a javaagent using 2 method:
Manually set enviorment variable JAVA_OPTS with java agent to point to /app/myjar.jar using cf set-env
Deploy a war file of the app using cf push from wlp server and set the java agent inside the server.xml file and attribute genericJvmArguments
Both of those methods didnt work, and either the deploy phase of the application failed or my features simply didnt work.
So I tried searching the application file system using cf files and came up with the app folder, but strangly it didn't have the same file as the folder I deploy and I couldn't find any connection to the deployed folder ot the build pack.
Can someone explain how this should be done correctly? namely, uploading the file and then how should I point to it from the enviorment variable/server file?
I mean should it be /app/something or maybe other path?
I have also seen the use of relative paths like #droplet.sandbox maybe its the way to address those files? and how should I access those folders from cf files
Thanks.
EDIT:
As I have been instructed in the comments I have added the jar file to the system, the problem is that when I add the javaagent variable to the enviorment variable JAVA_OPTS the deploy stage fails with the timeout error:
payload: {... "reason"=>"CRASHED", "exit_status"=>32, "exit_description"=>"failed to accept connections within health check timeout", "crash_timestamp"=>
1433864527}
The way I am assigning the javaagent is as follows:
cf set-env myApp JAVA_OPTS "path/agent.jar"
I have tried adding several location:
1. I have found that if I add the jar files to my WebContent folder I can find it in: /app/wlp/usr/servers/defaultServer/apps/myapp.war/resources/
2. I have copied the jar file from the /tmp location in the compilation phase to /home/vcap/app/agent.jar
3. I have located the jar file in /app/.java/jre/lib
none of those 3 paths worked.
I found out that if I give a wrong path the system behaves the same so it may be a path problem.
Any ideas?
Try this:
Put your agent jars in a folder called ".profile.d" inside your WAR package;
cf se your-app JAVA_OPTS -javaagent:/home/vcap/app/.profile.d/your.jar ;
Push the war to Bluemix.
Not sure if this is exactly the right answer, but I am using additional jar files in my Liberty application, so maybe this will help.
I push up a myapp.war file to bluemix. Within the war file, inside the WEB-INF folder, I have a lib folder that contains a number of jar files. The classes in those jar files are then used within the java code of my application.
myapp.war/WEB-INF/lib/myPlugin.jar
You could try doing something like that with the jar file(s) you need, building them into the war file.
Other than that, you could try the section Overlaying the JRE from the bluemix liberty documentation to add jars to the JRE.

Managing log4j.properties with lein

I'm trying to figure out how I can manage my log4j.properties file with leiningen. I'd like to be able to automatically include the file in the jars that lein creates as well as have the properties file be accessible to "lein swank" (and lein repl).
Right now I have the file in my project "root", but I get this error when I using logging from swank
[null] log4j:WARN No appenders could be found for logger (com.dev).
[null] log4j:WARN Please initialize the log4j system properly.
Thanks!
NOTE: I got my log4j.properties file from the blog post at http://www.paullegato.com/blog/log4j-clojure/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+clojure+(Planet+Clojure0
I'd be content (actually thrilled) configuring my logging output format from within Clojure, but I haven't found a way to do it yet.
You should put the log4j.properties file in the resources(top level folder - where project.clj, src, test, lib, classes are) folder of your lein project. That way it will be made available on the classpath and packaged with the project if you run lein jar.
Just to keep this current...
You should look at clj-logging-config. It allows you to configure your logger from Clojure.