I have a question regarding an Autosys job that I have been picking my head on but could not figure out. So, basically I have this AutoSys job that runs old spring boot application via a script File. When I say old, it uses spring.xml for dependency injection with context.getBean("beadIdFromSpringXml") as the process of generating bean as shown in below code:
# This is spring.xml file context
<context:property-placeholder
location="classpath:application-${spring.profiles.active}.properties" />
<bean id="myBean" class="com.example.MyBean">
<property name="propName1" value="${prop1}"/>
<property name="propName2" value="${prop2}"/>
</bean>
The bean is generated like example below:
public static void main(String[] args)
{
MyBean beanVariable = (MyBean) context
.getBean("myBean");
Then we have a script file that is run by AutoSys that starts the java project as shown below:
# If I echo ${PROFILE} here I do get "int" in logs
java -Dspring.profiles.active="${PROFILE}" .............
When starting the Job, it always ends up in runtime error by saying it cannot create the bean "myBean" cause it cannot find the {prop1}. So my guess is that the ${spring.profiles.active} is not being fetched by the spring boot app correctly. Has anyone faced this error before?
Related
I expected to be able to do something like this in my server.xml, but I could not get it to work:
<variable name="my.ldap.url" value="${LDAP_URL}" />
Setting it in jvm.options or server.env do not seem to be options either from what I can tell. Neither of those are parsing environment variables from my tests.
-Dmy.ldap.url=$LDAP_URL
Setting properties in my own files and using environment variables did not seem to work either. I tried something like this in my server.xml
<library id="configs">
<fileset dir="${server.config.dir}/configs" includes="*.properties" />
</library>
So I'm just lost for ideas right now. How do I take environment variables and inject them into an Open Liberty application as application properties?
I searched high and low for documentation on this, with no success.
In Jboss I was able to accomplish simple via
bin/standalone.sh -Dmy.ldap.url=$LDAP_URL
It should work for you exactly the way it does in Jboss:
wlp/bin/server start server1 -Dmy.ldap.url=$LDAP_URL
Your <variable> definition would create a Liberty configuration variable that resolves to the value of LDAP_URL in the environment, but it would not be set as a java system property.
If you're still seeing problems with passing the value on the command line you could check all java system properties by running:
wlp/bin/server dump {server name}
In the output zip file, the dump_{timestamp}/introspections/JavaRuntimeInformation.txt will show both the command line arguments and all defined java system properties.
I'd consider using Microprofile config, checkout this guide and see it does answer your questions.
It shows you how to inject variables using following schema:
#Inject #ConfigProperty(name="port")
private int port;
assuming there is PORT env entry in your system.
You can also use env variables in server configuration using server.xml for example:
<properties.db2.jcc serverName="${JDBC_HOST}" portNumber="${JDBC_PORT}" databaseName="${JDBC_DB}" sslConnection="${JDBC_SSL}"
user="${JDBC_ID}" password="${JDBC_PASSWORD}"/>
Details here https://openliberty.io/docs/latest/reference/config/server-configuration-overview.html
For your library point you would have to add it to your application via classloader, so I wouldn't recommend that. Like this:
<application name="myapp" type="ear" location="myapp.ear">
<classloader commonLibraryRef="configs" />
</application>
Hope it solves your problems.
The final answer I found to this, is you can inject environment variables into properties using the <appProperties> tag in your server.xml
Documentation is here
https://openliberty.io/guides/microprofile-config-intro.html#configuring-as-an-appproperties-element-scoped-by-application
A simple example of this using an environment variable looks like ...
<webApplication location="my.war" type="war">
<appProperties>
<property name="my.ldap.url" value="${LDAP_URL}"/>
</appProperties>
</webApplication>
I need to set Java's DNS cache TTL (networkaddress.cache.ttl) for an Amazon Elastic Beanstalk app running in Tomcat 8. Because EB can start and stop server instances at any time, I can't simply edit a Tomcat config file and the server and expect the change to persist.
I tried setting the networkaddress.cache.ttl and sun.net.inetaddr.ttl environment variables, but those had no effect. Amazon says calling java.security.Security.setProperty("networkaddress.cache.ttl" , "60"); "will not work if you run your application inside of Tomcat" (http://aws.amazon.com/articles/4035). What's a good way to set the TTL?
The problem is that I was doing it wrong. Setting the sun.net.inetaddr.ttl environment variable works. You can do this in your Elastic Beakstalk config file:
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: sun.net.inetaddr.ttl
value: 60
60 seconds is the value recommended by Amazon
Another option that seems a little nicer to me is to create and use a java.security file:
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: java.security.properties
value: /etc/myapp/java.security
container_commands:
00create_config_dir:
command: 'mkdir -p /etc/myapp'
ignoreErrors: true
01create_java_security_file:
command: 'echo "networkaddress.cache.ttl=60" > /etc/myapp/java.security'
ignoreErrors: true
If you are using spring framework, following is what I did to set the networkaddress.cache.ttl at the time of application initialisation.
Define a new Java class as follows.
package com.example.util;
public class SecurityManager {
public SecurityManager() {
java.security.Security.setProperty("networkaddress.cache.ttl", "60");
}
}
Ask spring framework to instantiate the object of above class as a singleton at the time on spring container creation.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="securityManager"
class="com.example.util.SecurityManager" scope="singleton" />
</beans>
If you are using Spring Boot, you can define a #Configuration
#Configuration
class SecurityManager {
init {
Security.setProperty("networkaddress.cache.ttl", "5")
}
}
I want to use my system environment variables (i.e use variable FOO that I have defined in my .bash_profile export FOO=BAR) for values in Spring's applicationContext.xml;
For example:
<bean id="dataSource" ...>
<property name="jdbcUrl" value="${FOO}" />
...
</bean>
I use both the Maven-tomcat-plugin and Tomcat inside IntelliJ to run my server.
Right now when my webapp starts up, it can't find the system variables.
What do I have to do to get Spring to read from my system environment variables?
P.S. I have already checked out how to read System environment variable in Spring applicationContext, but doesn't seem to work for me
System environment variables are different to the JVM system properties - which the spring PropertyPlaceholderConfigurer gives you access to. So you'd need to add to the JVM command:
java ... -DFOO=${FOO}
(where -DFOO is defining "FOO" as a JVM system property and ${FOO} is inserting the "BAR" value from your "FOO" environment variable)
See also the ServletContextPropertyPlaceholderConfigurer - with the SYSTEM_PROPERTIES_MODE_OVERRIDE property and a few other options.
try this (Spring Expression Language)
<bean id="dataSource" ...>
<property name="jdbcUrl" value="#{systemEnvironment.FOO}" />
...
</bean>
or add this line
<context:property-placeholder/>
to application context
I try to get an Environment variable specified in Tomcat's server.xml in a 'PropertyPlaceholderConfigurer' located in my jpa-spring.xml file.
So far, the setup looks as follows:
Tomcat server.xml
<Environment description="Identifies the server environement"
name="server-env"
type="java.lang.String"
value="dev" />
The in WebContent/META-INF/context.xml:
<Context>
<ResourceLink name="server-env" global="server-env" type="java.lang.String"/>
</Context>
Which is referenced in WebContent/WEB-INF/web.xml like:
<resource-env-ref>
<description>Identifies server environement</description>
<resource-env-ref-name>server-env</resource-env-ref-name>
<resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>
<!-- Spring Integration -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/jpa-spring.xml
</param-value>
</context-param>
And in /WEB-INF/config/jpa-spring.xml I try to get that variable as a replacement:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>WEB-INF/config/db.${server-env}.properties</value>
</list>
</property>
</bean>
This is a setup I put together using information from several articles found on the web.
However, I get an error like ...
Could not resolve placeholder 'server-env' in [WEB-INF/config/db.${server-env}.properties] as system property: neither system property nor environment variable found
05 Nov 2011 14:45:13,385 org.springframework.web.context.ContextLoader
ERROR Context initialization failed
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/config/db.${server-env}.properties]
... when starting tomcat.
What is the right approach to achieve what I am looking for?
I know that this question is similar to this, and this question. However, I even couldn't figure it out with the information from these answers.
Here are my suggestion
With the current set up, its really going to be complicated to read JNDI property server-env and use the same to load the property file.
The way you have assembled the spring application (and PropertyPlaceholderConfigurer), spring will try to look for the property server-env first in OS environment then in java system properties (passed from command using -D option). It finds it at neither of these places and hence fails.
So currently the easiest way out right now is to pass the value of server-env form command prompt of your application server (where you invoke java ; typical syntax would be -Dserver-env=dev). I leave this to you to figure out.
if above option appears a bit complicated, another easier way out is set an environment variable with name server-env to its appropriate values (on Windows its set server-env=dev. Plz check respect OS documentations for this).
Those Environment elements are setting up JNDI. Getting values out of JNDI isn't supported, by default, by any simple syntactic sugar in Spring.
http://www.theserverside.com/news/thread.tss?thread_id=35474#179220
might give you some useful ideas.
I am trying to bind connection to the DB using JNDI in my application that runs on JBoss. I did the following:
I created the datasource file oracle-ds.xml filled it with the relevant xml elements:
<datasources>
<local-tx-datasource>
<jndi-name>bilby</jndi-name>
...
</local-tx-datasource>
</datasources>
and put it in the folder \server\default\deploy
Added the relevant oracle jar file
than in my application I performed:
JndiObjectFactoryBean factory = new
JndiObjectFactoryBean();
factory.setJndiName("bilby");
try{
factory.afterPropertiesSet();
dataSource = factory.getObject();
}
catch(NamingException ne) {
ne.printStackTrace();
}
and this cause the error:
javax.naming.NameNotFoundException:
bilby not bound
then in the output after this error occured I saw the line:
18:37:56,560 INFO
[ConnectionFactoryBindingService]
Bound ConnectionManager 'jb
oss.jca:service=DataSourceBinding,name=bilby'
to JNDI name 'java:bilby'
So what is my configuration problem? I think that it may be that JBoss first loads and runs the .war file of my application and only then it loads the oracle-ds.xml that contain my data-source definition.
The problem is that they are both located in the same folder.
Is there a way to define priority of loading them, or maybe this is not the problem at all.
Any idea?
You should use such construction to call Datasource: java:bilby.
You can read more about that here:
Naming and Directory (JNDI) - JBOSS jndi Datasource: jdbc not bound
To check how the datasource is bound in the JNDI tree you should use the jmx-console
http://localhost8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss%3Aservice%3DJNDIView
and invoke the list() method.
Datasources are registered under "jdbc". In your case "jdbc/bilby"
EDIT: That was an example that works for me without spring.
Now found this example which injects a more complete JNDI name.
<bean id="idDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/bilby" />
</bean>