Configuring env-entry values in WebSphere Liberty? - websphere

In WAS Full Profile you can change the values for env-entries defined in an application's web.xml file while and after deployment. Is there any such feature in WebSphere Liberty profile?
Sample env-entry:
<env-entry>
<description>Some Config String</description>
<env-entry-name>MyConfigString</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Dev-Value to be replaced in Production during deployment</env-entry-value>
</env-entry>
This env-entry is injected with an #Resource(name = "MyConfigString") annotation.
The infocenter for IBM Worklight (which runs on Liberty) describes a way using jndiEntry elements in server.xml . I tried this on Liberty 8.5.5.3 but it does not work and still injects the default value from web.xml.
Has anybody found a working way to configure env-entry values in Liberty?

The Liberty profile doesn't currently support configuring bindings without modifying the ibm-*-bnd.xml files in the application. As a workaround, you can use:
#Resource(lookup="MyConfigString")
...in the application and:
<jndiEntry jndiName="MyConfigString" value='"xyz"'/>
...in server.xml as described in the knowledge center.

Related

Binding datasource to application when using springBootApplication in Liberty?

When deploying "regular" web apps to Liberty, I was used to binding the global datasource configured in Liberty's server.xml to the individual application by using a child element within the element, like this:
<application context-root="helloApp" location="..." name="helloApp" type="war">
<application-bnd>
<data-source id="db2appDs" name="jdbc/datasource" binding-name="jdbc/theDB"/>
</application-bnd>
...
</application>
<dataSource id="db2ds" jndiName="jdbc/theDB" type="javax.sql.DataSource">
...
</dataSource>
When configuring my first Spring Boot application to deploy to Liberty, I am trying to use the new <springBootApplication> element for it - but I don't seem to be able to add a binding for the datasource I want to use the same way, as this element doesn't seem to support such a child. (It seems to want only <classloader> as a child).
I've seen people suggest I use an #Resource annotation that includes both application-local JDNI name and global JNDI name for the datasorce - but that defeats the purpose, since I don't want to know what the global name is until deploy time.
Is there another way to do this, like we used to before? Or are applications deployed through <springBootApplication> expected to know the global JNDI name of the datasource(s) they want?
Application-defined datasources are not supported for <springBootApplication/>’s. While your application may certainly access a Liberty datasource using its global JNDI name, you should configure the spring.datasource.jndi-name property within your Spring Boot application as described in section 29.1.3 of the Spring Boot features reference. For your example try spring.datasource.jndi-name=jdbc/theDB.

Is there a way to pass application specific properties in Websphere?

We have a websphere application server where multiple applications are deployed. All applications use a common property(Key) but have different Value. For example :
spring.profiles.active=test in one application, spring.profiles.active=UAT in some other application.
Is it possible to pass these different values to the applications during start-up in Websphere ?
If we set these values in JVM options in the Generic JVM Arguments text box then it will become same for all the applications which we don't want.
Set these properties at application level in websphere so that when applications are started -
For application 1 - spring.profiles.active=test
For application 2 - spring.profiles.active=UAT
This document indicates that you can set the spring.profiles.active property in a WebApplicationInitializer per web application. Each application could then read its own specifically named property from System properties. Alternatively if using Liberty (the question didn't specify between traditional WebSphere vs Liberty), then you could use MicroProfile Config to define a property with a common name that is defined differently per application via appProperties, for example as shown in this knowledge center article. But you would still need the WebApplicationInitializer to read the value from MicroProfile Config.
An example would be something like the following:
Config config = ConfigProvider.getConfig();
servletContext.setInitParameter(
"spring.profiles.active",
config.getValue("ProfilesActive", String.class));
server.xml:
<server>
<featureManager>
<feature>mpConfig-1.3</feature>
.. other features
</featureManager>
<application location="app1.war">
<appProperties>
<property name="ProfilesActive" value="test"/>
</appProperties>
</application>
<application location="app2.war">
<appProperties>
<property name="ProfilesActive" value="UAT"/>
</appProperties>
</application>
</server>

LegacyCookieProcessor in standalone Tomcat and Spring Boot [duplicate]

My code is working on tomcat 8 version 8.0.33 but on 8.5.4 i get :
An invalid domain [.mydomain] was specified for this cookie.
I have found that Rfc6265CookieProcessor is introduced in tomcat 8 latest versions.
It says on official doc that this can be reverted to LegacyCookieProcessor in context.xml but i don't know how.
Please let me know how to do this.
Thanks
You can try in context.xml
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
reference:
https://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html
Case 1: You are using Standalone Tomcat & have access to change files in tomcat server
Please follow answer by #linzkl
Case 2: You are using Standalone Tomcat but you don't have access to change files in tomcat server
Create a new file called context.xml under src/main/webapp/META-INF folder in your application & paste the content given below
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
</Context>
When you deploy your application in Standalone Tomcat, the context.xml file you placed under META-INF folder will override the context.xml file given in tomcat/conf/context.xml
Note: If you are following this solution, you have to do it for every single application because META-INF/context.xml is application specific
Case 3: You are using Embedded Tomcat
Create a new bean for WebServerFactoryCustomizer
#Bean
WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return new WebServerFactoryCustomizer<TomcatServletWebServerFactory>() {
#Override
void customize(TomcatServletWebServerFactory tomcatServletWebServerFactory) {
tomcatServletWebServerFactory.addContextCustomizers(new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.setCookieProcessor(new LegacyCookieProcessor());
}
});
}
};
}
Enabling the LegacyCookieProcessor which is used in previous versions of Tomcat has solved the problem in my application. As linzkl mentioned this is explained in Apache's website https://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html.
The reason is that the new version of Tomcat does not understand the . (dot) in front of the domain name of the Cookie being used.
Also, make sure to check this post when you are using Internet Explorer. Apparently, it's very likely to break.
You can find context.xml in the following path.
tomcat8/conf/context.xml
<?xml version="1.0" encoding="UTF-8”?>
<!-- The contents of this file will be loaded for each web application —>
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!-- <Manager pathname="" /> -->
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor"/>
</Context>
The problem is still with Tomcat9. Same process need to follow for Tomcat 9 to set the class.
Add the class in context.xml file.
If you are using eclipse to run the application, need to set in the context.xml file in the server folder. Refer the below screenshot for more reference.
Hope this helps someone.
SameSite issue in tomcat version < 8.5.47 has resolved
In Tomcat 8.5.47 and bellow (Tomcat 8 versions), setting CookieProcessor tag to enable same site (as given bellow) in context.xml does not work due to a bug in Tomcat.
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" sameSiteCookies="none" />
If you find in this situation where it is not a easy thing to upgrade tomcat immediately (which I faced recently), or if you find any other case where you just need custom processing in cookies; You can write your own CookieProcessor class to get around.
Please find a custom CookieProcessor implementation and details of it's deployment steps here.
In my case I wrote a custom CookieProcessor based on LegacyCookieProcessor source code that allows tomcat 8.5.47 to enable SameSite attribute in cookies.
As mentioned by #atul, this issue persists in Tomcat 9. It will most likely persist moving forward with all future versions of Tomcat, since this is the new standard.
Using the legacy cookie processor (by adding the line above to the context.xml file) is working well for us. However, the true 'fix' is to adjust how your cookie is formed in the first place. This will need to be done in your application, not in Tomcat.
The new cookie processor does not allow the domain to start with a . (dot). Adjusting your cookie (if possible) to start with a value other than that will fix this problem without reverting to the old, legacy cookie processor.
Also, it should be obvious, but I didn't see it mentioned above: after updating the context.xml file, you need to restart the Tomcat service for the change to take effect.
Cheers!

Using ldapRegistry properties in Java running on Liberty Profile

I have some Java code running on Liberty Profile which authenticates with MS Active Directory and makes LDAP searches. The code use JNDI and does what it is intended to do. The problem is that the LDAP parameters are hard coded in Java. Works, but could be improved:
ldap.put(Context.PROVIDER_URL, "ldap://ad.foo.bar:389");
ldap.put(Context.SECURITY_PRINCIPAL, "CN=account,OU=A,DC=ad,DC=foo,DC=bar");
ldap.put(Context.SECURITY_CREDENTIALS, "apoorlykeptsecret");
...
ldapCtxt = new InitialDirContext(ldap);
Is it possible to pick the LDAP properties up from an ldapRegistry element in the server.xml file instead? Or am I on the wrong track? Is there a better way to approach this?
Yes, you should be able to configure that using the <ldapRegistry> element in server.xml.
For example:
<ldapRegistry id="ldap" realm="SampleLdapADRealm"
host="ldapserver.mycity.mycompany.com" port="389"
baseDN="cn=users,dc=adtest,dc=mycity,dc=mycompany,dc=com"
bindDN="cn=testuser,cn=users,dc=adtest,dc=mycity,dc=mycompany,dc=com"
bindPassword="testuserpwd"
ldapType="Microsoft Active Directory">
<activedFilters
userFilter="(&(sAMAccountName=%v)(objectcategory=user))"
groupFilter="(&(cn=%v)(objectcategory=group))"
userIdMap="user:sAMAccountName"
groupIdMap="*:cn"
groupMemberIdMap="memberOf:member" >
</activedFilters>
</ldapRegistry>
For full doc see: Configuring LDAP user registries in Liberty
As an alternative quick approach, you could put those values in your server.xml configuration as JNDI entries and obtain the values in your application by JNDI lookup. For example:
<jndiEntry jndiName="ldap/provider_url" value="ldap://ad.foo.bar:389"/>
<jndiEntry jndiName="ldap/secuirty_principal" value="CN=account,OU=A,DC=ad,DC=foo,DC=bar"/>
<!-- WARNING: Storing passwords is JNDI is not secure -->
<jndiEntry jndiName="ldap/security_credentials" value="apoorlykeptsecret"/>
String providerUrl = InitialContext.doLookup("ldap/provider_url");
// etc...

How to configure JSF 2.0 application's project stage via JNDI in Tomcat

been struggling to find a way to configure Tomcat 7.0.11 so that my web application would use project stage setting from Tomcat's config. So far - no luck. The idea is to set this property in Tomcat server/host/application wide but not to set it in web.xml. Any ideas? I am using MyFaces JSF 2 implementation 2.0.5.
The specification says that the JSF implementation looks up the Project Stage using JNDI under java:comp/env/jsf/ProjectStage. If not found it uses the context parameter javax.faces.PROJECT_STAGE from your web.xml. This means that if defined/found on your Tomcat using JNDI, the value of preferred over the web.xml setting.
There are two things you can do:
Option 1: Overwrite the context parameter: This means that context parameter is set/overwritten using the Tomcat server.xml or context.xml. You need to put this in your <Context>-tag:
<Parameter name="javax.faces.PROJECT_STAGE" value="Production" override="false" />
Careful: override="false" here means that this parameter can NOT be overriden by the web.xml (not the other way around)!
Option 2: Configure a resource that can be found using JNDI: By using this that JSF implementation can resolve the project stage using the JNDI lookup.
<Environment name="jsf/ProjectStage" value="Production" type="java.lang.String" override="false"/>
You can also move this to the <GlobalResources>-tag in your server.xml. In this case you would need to reference this in your <Context>-tag by using <ResourceLink>-tag.

Resources