How to override portal-impl jar classes in Liferay ext-plugin - java

I want to override two portal-impl.jar classes NtlmFiler.java and NtlmPostFilter.java, I have created an ext-plugin project and placed my custom written classes in ext-impl/src but I am unable to configure my spring.xml file to use my newly written classes instead of portal-impl classes, maybe i am totally wrong about doing it this way.
My ext-spring.xml code is :
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="com.liferay.portal.servlet.filters.sso.ntlm.NtlmFilter"
class="com.liferay.portal.servlet.filters.sso.ntlm.NtlmFilter">
<property name="ntlmFilter">
<bean class="com.sso.ntlm.filter.CustomNtlmFilter">
<property name="CustomNtlmFilter" ref="customNtlmFilter" />
</bean>
</property>
</bean>
<bean id="com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter"
class="com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter">
<property name="ntlmPostFilter">
<bean class="com.sso.ntlm.filter.CustomNtlmPostFilter">
<property name="CustomNtlmPostFilter" ref="customNtlmPostFilter" />
</bean>
</property>
</bean>
Note: The idea is to solve this problem

As the NtlmFilter is no Spring bean, there is no use to define it in ext-spring.xml.
See portal.properties:
# ... and the filter
# com.liferay.portal.servlet.filters.sso.ntlm.NtlmFilter must be referenced
# in web.xml.
So you just need to reference your filter class instead in liferay-web.xml or web-ext.xml (I don't know if the later works for overrides).
The same applies to the NtlmPostFilter.

Related

Problems using multiple PropertySourcesPlaceholderConfigurer

Ok, I have been fighting this too long, time to ask for help. HELP!!!
I'm deploying an indipendent jar maven project that will be used as dependency into other projects.
I need that this jar loads its own properties file ("versione.properties" released inside the jar) when the application that will use it, will start up but I want that the application doesn't care about it. This should be in charge on the lib.
I want that who will use this lib, will have just to
include the right dependency inside his pom.xml
add <import resource="classpath*:*-context.xml" /> inside his spring app-context.xml to be sure to include also the lib-context.xml during the spring-context initialization
For this reason, the jar has its own spring lib-context.xml file as the following:
<context:component-scan base-package="it.eng.inps.comppsr" />
<bean id="propertyPlaceholderConfigurer2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<value>classpath:versione.properties</value>
</list>
</property>
</bean>
<bean id="version" class="it.eng.inps.comppsr.util.Versione">
<property name="buildVersion" value="${comppsrutil.build.version}"/>
<property name="buildDate" value="${comppsrutil.build.timestamp}"/>
</bean>
As you can immagine, "versione.properties" file contains comppsrutil.build.version and comppsrutil.build.timestamp.
During my tests, I've tried also <value>classpath*:versione.properties</value>, <value>classpath:/versione.properties</value> and <value>classpath:*/versione.properties</value> but with no luck.
This library is used by a web-service application (a war inside an ear file) and this application has got its own spring app-context.xml that loads it own properties file as described by the following code snippet
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="lookupPropertiesInitializer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<value>file:///#{lookupPropertiesInitializer.pathToProperties}</value>
<value>classpath*:version.properties</value>
</list>
</property>
</bean>
<context:component-scan base-package="it.eng.inps.util, it.eng.inps.comppsr" />
<import resource="classpath*:*-context.xml" />
When I start the application (it runs inside JBoss EAP 7.3), I get this error:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'comppsrutil.build.version' in value "${comppsrutil.build.version}"
So, it seems that something goes wrong within the lib initialization.
If I rename the "versione.properties" file in "version.properties" (so with the same name used by the app properties file), this error desappear, I think, because it is loaded by the application PropertyPlaceholderConfigurer, so the lib property file is well located.
For this reason I think that the bean propertyPlaceholderConfigurer2 defined inside lib-context.xml, doesn't work as I expected but I didn't understand why.
Does anyone give me any tips?

DAO null in spring bean class with xml config

I'm trying to inject the uploadDao in the bean DemoHandler (XML below). But as expected it is Null. The question is how do I inject the DAO correctly.
Right now, there is a method call from WebUploadServiceImpl to DemoHandler and I can add 1 more parameter and send the value I need from uploadDao, but then that method is reused for multiple java classes and all those methods need to be refactored and that new param will not be relevant to the other classes.
Is there a way to get uploadDao to inject in DemoHandler? Any help is much appreciated. Thanks
Spring XML:
<bean id="wuService" class="com.abcd.service.WebUploadServiceImpl">
<property name="uploadDao" ref="uploadDao" />
<property name="webHandlers">
<set>
<bean class="com.abcd.service.handler.DemoHandler" />
</set>
</property>
</bean>
Code:
public class DemoHandler {
private UploadDao uploadDao;
public List handleM(...) {
...
Period period = uploadDao.anyMethod(..); --- Null here
}
}
If DemoHandler needs to set a dao, why don't you do something like this ...
<bean id="uploadDao" class="whatever.dao.UploadDaoImpl"/>
<bean id="wuService" class="com.abcd.service.WebUploadServiceImpl">
<property name="uploadDao" ref="uploadDao" />
<property name="webHandlers">
<set>
<bean class="com.abcd.service.handler.DemoHandler">
<property name="uploadDao" ref="uploadDao" />
</bean>
</set>
</property>
</bean>
You just need to replicate the injection mechanism already used in WebUploadServiceImpl. You haven't shown that code, I donĀ“t know if you use #Autowired, a set method or any other possibility.

Using Spring Integration SpEl inside value tag

I am trying to set the properties file inside a class that extends the PropertyPlaceholderConfigurer based upon the environment (local, dev, ref, qa, prod)
My folder structure looks like the following.
properties
environment.properties
server-local.properties
server-ref.properties
server-prod.properties
email-local.properties
email-ref.properties
email-prod.properties
cache-local.properties
cache-ref.properties
cache-prod.properties
The environment.properties has a property
environment.stage=local (or whatever env this is)
My Spring Integration context statements look something like this:
<context:property-placeholder location="classpath:properties/*.properties" />
<bean id="propertyPlaceholder" class="com.turner.bvi.BviPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:properties/environment.properties</value>
<value>classpath:properties/*-${environment.stage}.properties</value>
</list>
</property>
</bean>
What I want to do is have only the properties file from the particular environment stage load (be it local, ref, prod .... etc.). How do I get just this second set of properties files to load based upon environment.stage?
Thanks for the help in advance.
You can use Spring profiles for this, it would be something like this:
<context:property-placeholder location="classpath:properties/*.properties" />
<beans profile="local">
<bean id="propertyPlaceholder" class="com.turner.bvi.BviPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:properties/environment.properties</value>
<value>classpath:properties/*-local.properties</value>
</list>
</property>
</bean>
</beans>
<beans profile="dev">
<bean id="propertyPlaceholder" class="com.turner.bvi.BviPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:properties/environment.properties</value>
<value>classpath:properties/*-local.properties</value>
</list>
</property>
</bean>
</beans>
...
Setting an environment variable can be done using spring_profiles_active (or spring_profiles_default). In Unix try exporting SPRING_PROFILES_DEFAULT=local
You can alternativerly use the JVM parameters like -Dspring.profiles.active=local
In case you need to maintain the environment variables as they are, you can implement a custom ActiveProfilesResolver as described in here: Spring Profiles: Simple example of ActiveProfilesResolver?
Thank you all for your help. I was able to take snippets of all your suggestions and come up with a solution using "environmentProperties" in the Spring context.
The problem with trying to use a in the context was that it had not been set at the time MY class was trying to resolve the ${environment.stage}... Or at least that is what I gathered from searching other posts.
If my properties file structure looks like this:
properties
environment.properties
server-local.properties
server-ref.properties
server-prod.properties
email-local.properties
email-ref.properties
email-prod.properties
cache-local.properties
cache-ref.properties
cache-prod.properties
I was able to set the Environment property 'env' to the correct value through Chef or through a Docker container and use the following code.
<!-- Register the properties file location -->
<context:property-placeholder location="classpath:properties/*.properties" />
<bean id="propertyPlaceholder" class="com.turner.bvi.BviPropertiesUtil">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:properties/environment.properties</value>
<value>classpath:properties/*-#{systemEnvironment['env']}.properties</value>
</list>
</property>
</bean>
I could have put each of the property sets under its own directory and had
<value>classpath:properties/#{systemEnvironment['env']}/*.properties</value>
Again, thank you all for your help.

Spring - Paths in applicationContext.xml

I am defining a freemarker bean in my applicationContext.xml and this bean needs a path to my template-directory.
It used to be:
src/main/webapp/template/
But i now want to store my templates under:
src/main/resources/template/
It used to look like:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/template/email/"/>
</bean>
Can anyone please help me to correctly define the new path?
Answering as a proper answer, so you can close the question.
You should use "classpath:" prefix to reference resources located in the classpath.
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="classpath:/template/email/"/>
</bean>

How do I read JVM arguments in the Spring applicationContext.xml

I have a JSF web application with Spring and I am trying to figure out a way to reference the JVM arguments from the applicationContext.xml. I am starting the JVM with an environment argument (-Denv=development, for example). I have found and tried a few different approaches including:
<bean id="myBean" class="com.foo.bar.myClass">
<property name="environment">
<value>${environment}</value>
</property>
</bean>
But, when the setter method is invoked in MyClass, the string "${environment}" is passed, instead of "development". I have a work around in place to use System.getProperty(), but it would be nicer, and cleaner, to be able to set these values via Spring. Is there any way to do this?
Edit:
What I should have mentioned before is that I am loading properties from my database using a JDBC connection. This seems to add complexity, because when I add a property placeholder to my configuration, the properties loaded from the database are overridden by the property placeholder. I'm not sure if it's order-dependent or something. It's like I can do one or the other, but not both.
Edit:
I'm currently loading the properties using the following configuration:
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc.mydb.myschema"/>
</bean>
<bean id="props" class="com.foo.bar.JdbcPropertiesFactoryBean">
<property name="jdbcTemplate">
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="myDataSource" />
</bean>
</property>
</bean>
<context:property-placeholder properties-ref="props" />
You can use Spring EL expressions, then it is #{systemProperties.test} for -Dtest="hallo welt"
In your case it should be:
<bean id="myBean" class="com.foo.bar.myClass">
<property name="environment">
<value>#{systemProperties.environment}</value>
</property>
</bean>
The # instead of $ is no mistake!
$ would refer to place holders, while # refers to beans, and systemProperties is a bean.
May it is only a spelling error, but may it is the cause for your problem: In the example for your command line statement you name the variable env
(-Denv=development, for example...
But in the spring configuration you name it environment. But both must be equals of course!
If you register a PropertyPlaceholderConfigurer it will use system properties as a fallback.
For example, add
<context:property-placeholder/>
to your configuration. Then you can use ${environment} in either your XML configuration or in #Value annotations.
You can load a property file based on system property env like this:
<bean id="applicationProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="searchSystemEnvironment" value="false" />
<property name="locations">
<list>
<value>classpath:myapp-${env:prod}.properties</value>
</list>
</property>
</bean>
If env is not set default it to production otherwise development and testing teams can have their flavor of app by setting -Denv=development or -Denv=testing accordingly.
Use #{systemProperties['env']}. Basically pass the propertyName used in the Java command line as -DpropertyName=value. In this case it was -Denv=development so used env.
Interestingly, Spring has evolved to handled this need more gracefully with PropertySources:
http://spring.io/blog/2011/02/15/spring-3-1-m1-unified-property-management/
With a few configurations and perhaps a custom ApplicationInitializer if you are working on a Web app, you can have the property placeholder handle System, Environment, and custom properties. Spring provides PropertySourcesPlaceholderConfigurer which is used when you have in your Spring config. That one will look for properties in your properties files, then System, and then finally Environment.
Spring 3.0.7
<context:property-placeholder location="classpath:${env:config-prd.properties}" />
And at runtime set:
-Denv=config-dev.properties
If not set "env" will use default "config-prd.properties".

Categories