Liferay 7 MessageListener osgi module - osgi

When I worked with the liferay 6.1 I created an application that received the message.
Java class:
public class MailMessageBus implements MessageListener
\src\main\webapp\WEB-INF\src\META-INF\messaging-spring.xml file:
<beans
default-destroy-method="destroy"
default-init-method="afterPropertiesSet"
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">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="messagingConfigurator" class="com.liferay.portal.kernel.messaging.config.PluginMessagingConfigurator">
<property name="messageListeners">
<map key-type="java.lang.String" value-type="java.util.List">
<entry key="mail-send-message">
<list value-type="com.liferay.portal.kernel.messaging.MessageListener">
<ref bean="messageListener.mail_listener" />
</list>
</entry>
</map>
</property>
<property name="destinations">
<list>
<ref bean="destination.mail"/>
</list>
</property>
</bean>
<!-- Destination class -->
<bean id="destination.mail" class="com.liferay.portal.kernel.messaging.ParallelDestination">
<property name="name" value="mail-send-message" />
</bean>
<!-- Listener class -->
<bean id="messageListener.mail_listener" class="customportlet.AMessageBusListener.MailMessageBus" />
and \src\main\webapp\WEB-INF\web.xml file:
...
<context-param>
<param-name>portalContextConfigLocation</param-name>
<param-value>/WEB-INF/src/META-INF/messaging-spring.xml</param-value>
</context-param>
...
How can I do the same for liferay 7 in the OSGi module? OSGi module does not have a web.xml file.
Thank you very much!

I'm trying to accomplish the same thing, and based on what I've found so far the web.xml is unnecessary. OSGi modules seem to detect spring configuration automatically, according to this resource:
https://docs.spring.io/spring-osgi/docs/current/reference/html/app-deploy.html
Just put your configuration in xml files located at META-INF/spring

Related

deployerConfigContext.xml has no effect

I tried to get a CAS-server up and running using https://github.com/apereo/cas-overlay-template for a side project (I'm a student), but I have never used maven or spring before.
I'm trying to hook my own IPersonAttributeDao into the CAS-server. However, when I put my deployerConfigContext.xml under src/main/webapp/WEB-INF/, nothing actually changed when I repackaged (using the build script) and deployed to tomcat8. (Yes, I did restart tomcat).
Below the contents of my deployerConfigContent.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<!-- Login stays the default casuser:Mellon, no idea why -->
<entry key="test" value="1234"/>
</map>
</property>
</bean>
<!-- DO NOT EVER PUT THIS BEAN IN PRODUCTION!!! -->
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler"/>
</list>
</property>
</bean>
<!-- <bean id="attributeRepository" class="class.i.am.trying.to.hook.in">
</bean>-->
<!-- This doesn't seem to work -->
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</map>
</property>
</bean>
</beans>
What am I missing?
UPDATE:
I reread the documentation (https://apereo.github.io/cas/5.0.x/), and found that deployerConfigContext.xml was supposed to be in resources, and not in webapp/WEB-INF as I found on the internet. I moved it, and now I'm finally getting errors in the log (which means the file is being read).
Error below:
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] for bean with name 'authenticationManager' defined in class path resource [deployerConfigContext.xml]
I found a reference to PolicyBasedAuthenticationManager in the docs, but trying that gave the same error (with the other classname ofcourse).
Bean classes of enabled beans must be deployed in bean archives.
A library jar, EJB jar, application client jar or rar archive is a
bean archive if it has a file named beans.xml in the META-INF
directory. The WEB-INF/classes directory of a war is a bean archive if
there is a file named beans.xml in the WEB-INF directory of the war. A
directory in the JVM classpath is a bean archive if it has a file
named beans.xml in the META-INF directory.
One suggestion, if you are using Spring, you can also set #Annotation to define beans.

Spring scopes in embedded web app in Jetty server

I configured Jetty to start web app from spring context, e.i. there are two contexts:
external context which runs Jetty
internal which is run by Spring DispatcherServlet
Here is the definition of external context:
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
<bean id="servletHolder" class="org.eclipse.jetty.servlet.ServletHolder">
<constructor-arg name="name" value="dispatcher"/>
<constructor-arg name="servlet" value="org.springframework.web.servlet.DispatcherServlet"/>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:dispatcher-context.xml"/>
</map>
</property>
<property name="initOrder" value="0"/>
</bean>
<bean id="servletHandler" class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<array>
<ref bean="servletHolder"/>
</array>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="servletName" value="dispatcher"/>
<property name="pathSpec" value="/*"/>
</bean>
</list>
</property>
</bean>
<bean id="contextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/spring"/>
<property name="servletHandler" ref="servletHandler"/>
</bean>
<bean class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<constructor-arg name="port" value="9999"/>
<property name="handler" ref="contextHandler"/>
</bean>
</beans>
It refers to dispatcher-context.xml which is "internal".
So far it work fine unless I need to inject beans from external context into controller's beans from internal context.
Is there any way to define bean in outer scope and inject it into controller?
It would be useful in unit-test or using this server as a part of bigger existing app.
The full code is available here: https://github.com/zjor/embedded-jetty/tree/master/spring-mvc-jetty
So far I've found a workaround, I've used a combination of Jersey with Jetty and configured everything via Spring.
Code is available here: https://github.com/zjor/embedded-jetty/tree/master/jersey-jetty

Cannot resolve #Value (Spring 4)

I am trying to load different property files for different profiles.
I am running Tomcat 8.0, and using Spring 4.1.4.
In the xml I have defined my active profile like this:
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
In my spring configuration xml I have defined following profiles:
<beans profile="dev, default">
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db_dev.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
</beans>
<beans profile="qual">
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db_qual.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
</beans>
In both properties file, I have defined following keys:
email.targetURL
email.from
The values are different for different profiles.
In my java Class i have the following fields:
#Value("${email.targetURL}")
String targetURL;
#Value("${email.from}")
String from;
When I run the application, value is not resolved, It simply prints out a string for example, "${email.from}".
The Class is a Spring Component and has also other autowired fields that are processed ok.
Any sugestions?

Load webserver context.xml using Spring

Fairly new to Spring, so I'm having some trouble with this. I'm trying to use LDAP security with Spring. I can use a properties file I created inside the webapp itself. But what I would like to do is load and read the context.xml file of the server (it has all the values I need for this and other applications).
This is what I have:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>/WEB-INF/properties/dataUploadProperties.properties</value>
<value>/WEB-INF/properties/globalProperties.properties</value>
<value>context.xml</value>
</list>
</property>
</bean>
I'm able to load and read the 2 properties files, but the context.xml is not found. Does it need to be the absolute path on the server?
Thanks
Chris
So the first thing I would recommend is to use Spring Security. It has an already build in LDAP support.
but the context.xml is not found
Normally this (reading the context.xml directly) is not the way you should go.
Instead, define some properties and or JNDI resources in the context.xml and then use them in the spring configuration.
For example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jee="http://www.springframework.org/schema/jee"
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
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- access via jndi -->
<jee:jndi-lookup id="jndiEmailSession"
jndi-name="java:comp/env/email/session/myEmailSession" />
<!-- direct access for properties required the SERVLET contect property
place older configurer, then it works like properties from normal
property files -->
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> <property name="locations" value="classpath*:META-INF/spring/*.properties" /> </bean>
<bean class=Demo>
<property name="someString" value="${simpleValue}" />
</bean>
</beans>
context.xml:
<Resource name="email/session/myEmailSession"
type="javax.mail.Session"
auth="Container"
password="secret"
mail.debug="false"
mail.transport.protocol="smtp"
mail.smtp.auth="true"
mail.smtp.user="test#example.com"
mail.smtp.host="mail.example.com"
mail.smtp.from="test#example.com"/>
<Parameter name="simpleValue" value="any" override="false" />

Spring DB2 JPA Entity Manager Problem

I'm trying to configure Spring, JPA and DB2 in order to have the entity manager instance to be used in my spring controllers but according how I have configured Spring this not happens.
These are the two attempts of configuration of spring:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" />
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="em" />
</bean>
<bean id="em"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="fileUtility" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
<property name="database" value="DB2" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
the second is this:
<!-- Entity manager factory bean. -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Sample" />
</bean>
<!-- Entity manager bean. -->
<bean id="em" factory-bean="entityManagerFactory"
factory-method="createEntityManager" />
and the entity manager is injected in this way:
<bean id="messageService" class="utilities.services.impl.MessageServiceImpl">
<property name="entityManager" ref="em" />
</bean>
but I have always this exception:
Caused by: java.lang.IllegalArgumentException: methods with same signature createEntityManager() but incompatible return types: [interface com.ibm.websphere.persistence.WsJpaEntityManager, interface org.apache.openjpa.persistence.OpenJPAEntityManagerSPI]
I don't know how can be fixed. Has anyone encountered this problem?
Thanks in advance.
[EDIT]
This is my persistence.xml:
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<persistence-unit name="fileUtility"
transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<mapping-file>META-INF/mapping.xml</mapping-file>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:db2://localhost:50000/db2admin" />
<property name="openjpa.ConnectionDriverName" value="COM.ibm.db2.jdbc.app.DB2Driver" />
<property name="openjpa.ConnectionUserName" value="db2admin" />
<property name="openjpa.ConnectionPassword" value="XXXX" />
<property name="openjpa.FlushBeforeQueries" value="true"/>
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
</properties>
</persistence-unit>
<persistence-unit name="fileUtility2" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>file_ds</jta-data-source>
<mapping-file>META-INF/mapping.xml</mapping-file>
<properties>
<property name="openjpa.Log" value="SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72"/>
</properties>
</persistence-unit>
</persistence>
WebSphere has a JPA implementation bundled. So no need to add openjpa to your lib. In fact, WebSphere is using OpenJPA, so you are not losing anything. Look here for more details
When using a jda-data-source, you need to have transaction-type="JTA". Also, you should not specify connection properties - they are specified in the datasource.
And get rid of the <provider> - the document I linked says:
If no JPA provider is configured in the element of the persistence.xml file within an EJB module, the default JPA provider that is currently configured for this server is used
I believe you're doing the wrong configuration, because you're configuring it "à la Tomcat". If you're using a Java EE application server, such as WAS, you should:
In Spring application context xml file
configure the DAO bean by a <bean> definition
configure the JNDI definition for the datasource created in the application server via a
<jee:jndi-lookup>
definition; the
name
attribute should be
persistence/XXX, where XXX shall match the
<persistence-unit name="XXX" transaction-type="JTA">
in persistence.xml file
The id attribute in the
<jee:jndi-lookup id=YYY> should point to the
name=YYY parameter of the Entity Manager definition in the DAO, this is to say,
#PersistenceContext(name=YYY) EntityManager em;
Specify
<tx:annotation-driven /> and
<tx:jta-transaction-manager />
In file
web.xml of your web app you should include a definition using the xml tag
<persistence-unit-ref> whose
<persistence-unit-ref-name> parameter shall be the
persistence/XXX JNDI name as specified in persistence.xml (shown above).
Finally, you should create a JNDI definition in the application server (AS dependant) that defines the JNDI name for the JDBC connection. This name should match the
<jta-data-source> xml tag in the persistence.xml file, and it is the only link between the JPA definition and the JDBC defined in the application server.
To round up:
Application Context Spring file
<bean class="DAO implementation class" />
<jee:jndi-lookup id="YYY" jndi-name="persistence/XXX" />
<tx:annotation-driven />
<tx:jta-transaction-manager />
persistence.xml file
<persistence-unit name="XXX" transaction-type="JTA">
<jta-data-source>jdbc/DSN</jta-data-source>
</persistence-unit>
web.xml file
...
<persistence-unit-ref>
<persistence-unit-ref-name>persistence/XXX</persistence-unit-ref-name>
</persistence-unit-ref>
...
DAO (only #PersistenceContext shown)
...
#PersistenceContext(name = "YYY")
EntityManager em;
...
Application Server: jdbc/DSN links to the connection definition, where the driver for the DBM is. Depends on both the AS and the DBM used.
Thus, you may see the connection between the DAO -> Spring Application Context file -> persistence.xml and web.xml files -> Application Server JNDI names. IF you're using a full Java EE application server (such as WAS, Weblogic or GlassFish) you don't have to use Spring interface modules; only defnitions in the app server (see Spring documentation, section 12.6.3).

Resources