Tribune

Home » Liferay Portal » English » 3. Development

Vista Combinata Vista Piatta Vista ad Albero
Discussioni [ Precedente | Successivo ]
toggle
Jianyu Tang
What's the classloading model of Liferay
12 marzo 2013 1.35
Risposta

Jianyu Tang

Punteggio: New Member

Messaggi: 6

Data di Iscrizione: 15 febbraio 2012

Messaggi recenti

Hi, when I develop liferay hook / plugins, sometime I have weird class loading issues like slf4j / log4j / spring jms template.

As Liferay will copy some jar files like util-java.jar when deploy some hook / plugin, can I know if Liferay following the standard JEE web app class loading pattern? You can refer this:

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:

Bootstrap classes of your JVM
System class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Common class loader classes (described above)

Thanks.
David H Nebinger
RE: What's the classloading model of Liferay
12 marzo 2013 5.25
Risposta

David H Nebinger

Punteggio: Liferay Legend

Messaggi: 6274

Data di Iscrizione: 1 settembre 2006

Messaggi recenti

Liferay does adhere to the app container's normal class loader hierarchy. The part that you're missing is the understanding of the context that your plugin operates...

Hooks actually apply themselves to the ROOT application context in some cases. For example, a JSP hook replaces the JSP files from ROOT w/ the copies that the hook provides. So at runtime, the JSP file is actually part of ROOT and not separately as part of your hook. This can lead to issues if you include a jar file in your Hook for your JSP because the JSP is now part of ROOT and has no visibility on whatever jar file you had included.

Long story short, you must be aware of how your hook functions at runtime and which web application it actually applies to (your hook's web app or ROOT's web app).
Jianyu Tang
RE: What's the classloading model of Liferay
19 marzo 2013 3.40
Risposta

Jianyu Tang

Punteggio: New Member

Messaggi: 6

Data di Iscrizione: 15 febbraio 2012

Messaggi recenti

Thank you David. I do have lot of questions about the details, is there any documentation or book so I can learn?

I have spent quite some time to resolve an issue related to this. Can you explain how can I use a 3party library in my own hook? Actually It's spring-integration-jms, and trying to send a jms message from the audit-hook. But if I packaged spring-jms into the hook, I got below error:

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframew
ork.jms.core.JmsTemplate' to required type 'org.springframework.jms.core.JmsTemplate' for property 'jmsTemplate'; nested excepti
on is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.jms.core.JmsTemplate] to required type
[org.springframework.jms.core.JmsTemplate] for property 'jmsTemplate': no matching editors or conversion strategy found

If I removed spring-jms out from the hook.war, I got:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'auditMessageSender' defined i
n ServletContext resource [/WEB-INF/classes/META-INF/audit-producer.xml]: Initialization of bean failed; nested exception is jav
a.lang.NoClassDefFoundError: org/springframework/jms/core/JmsTemplate

Neither error make sense to me. You can look at the original question from me below.

http://www.liferay.com/en/community/forums/-/message_boards/message/21880197
David H Nebinger
RE: What's the classloading model of Liferay
19 marzo 2013 6.36
Risposta

David H Nebinger

Punteggio: Liferay Legend

Messaggi: 6274

Data di Iscrizione: 1 settembre 2006

Messaggi recenti

Jianyu Tang:
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframew
ork.jms.core.JmsTemplate' to required type 'org.springframework.jms.core.JmsTemplate' for property 'jmsTemplate'; nested excepti
on is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.jms.core.JmsTemplate] to required type
[org.springframework.jms.core.JmsTemplate] for property 'jmsTemplate': no matching editors or conversion strategy found


This is an example of a class loading issue. Your hook has one context (where the classes are) but the code is invoked within the portal's context (where the classes aren't).

The good news is that this is resolved by using a correct architecture... The auditing system uses the Liferay Message Bus to publish auditing messages. Instead of trying to push to JMS directly as you are, instead create a listener on the destination of the LMB. In your listener, you can bridge from the LMB message to JMS. This will resolve your class loader issues while still allowing the publication to JMS.
Jelmer Kuperus
RE: What's the classloading model of Liferay
19 marzo 2013 7.35
Risposta

Jelmer Kuperus

Punteggio: Liferay Legend

Messaggi: 1190

Data di Iscrizione: 10 marzo 2010

Messaggi recenti

I am not sure what the situation is like in liferay 6.1 and up but in 6.0.x liferay would use it's own spring PortletContextLoaderListener that is able to instantiate classes both portal classes (eg those in ROOT/WEB-INF/lib and classes) and hook classes (your-hook/WEB-INF/lib and classes) a problem arises when you have the same class in both classloaders (eg spring libraries) The easiest way to solve it would be to not use liferay's com.liferay.portal.kernel.spring.context.PortletContextLoaderListener but spring's org.springframework.web.context. ContextLoaderListener but in many cases this might not be an option and you'll need to come up with some sort of workaround
David H Nebinger
RE: What's the classloading model of Liferay
19 marzo 2013 9.46
Risposta

David H Nebinger

Punteggio: Liferay Legend

Messaggi: 6274

Data di Iscrizione: 1 settembre 2006

Messaggi recenti

Actually, Jelmer, in 6.1.1 PortletContextLoaderListener has been completely deprecated and now is just an empty implementation class (to facilitate deployment of older portlets which still have the reference in place).