フォーラム

ホーム » Liferay Portal » English » 3. Development

構造的に表示 平面上に表示 ツリー上に表示
スレッド [ 前へ | 次へ ]
toggle
Guido Kaltwasser
Tomcat 6.x classloader issue
2008/10/09 10:04
答え

Guido Kaltwasser

ランク: New Member

投稿: 18

参加年月日: 2008/09/15

最近の投稿

Dear all,

Presumably, we discovered a classloader issue with Tomcat 6.0.x and apparently also with Tomcat 5.5.x

Within the portal core we customised class com.liferay.portal.service.OrganizationServiceUtil so that users can choose thier location during the registration process. As recommended we overwrite this class in the ext environment and deploy it to tomcat. This class is packaged to two jar files.

1) {catalina.home} /lib/ext/ext-services.jar (customised class) and
2) {catalina.home} /lib/ext/portal-service.jar (original class)

According to the classloader specification of tomcat, ext-service.jar should be read first and therefore the customised class as well. But when I invoke the create_account.jsp the original class is called and we get an java.lang.NoSuchMethodError exception, because the method we call with that jsp sits within the customised class.

We found a workaround for this issue by copying the class files into the {catalina.home} /lib/ folder to force tomcat to load this class first. That worked!

From our point of view, that does not seam to be the right way. Is there any one who can tell us what we are doing wrong...

Cheers Guido

Environment:
-ubuntu
-java 6
-ant 1.7
-liferay 5.1.2
-Tomcat 6 Bundle
-HSQL (for development)
Alex Wallace
RE: Tomcat 6.x classloader issue
2008/10/09 9:06
答え

Alex Wallace

ランク: Liferay Master

投稿: 640

参加年月日: 2007/11/04

最近の投稿

Because of classloading differences and sometimes unexpected behavior, the recommendation is that your overrides use their own package name or class name (different from originals) and that you also change the process that used the class you overrode, such as a struts action, or perhaps you will need to create a custom service to use your override as well.

I hope this makes sens... And helps...
Guido Kaltwasser
RE: Tomcat 6.x classloader issue
2008/10/09 10:10
答え

Guido Kaltwasser

ランク: New Member

投稿: 18

参加年月日: 2008/09/15

最近の投稿

Hi Alex,

thanks, we will discuss this approach in tomorrows meeting.

What I forgot to mention is, that we have a couple of development PC and with one PC does it work and with the other PC not. Up till now we were not able to find out why.. That drives me mad.

Cheers Guido
Mika Koivisto
RE: Tomcat 6.x classloader issue
2008/10/11 10:39
答え

Mika Koivisto

LIFERAY STAFF

ランク: Liferay Legend

投稿: 1513

参加年月日: 2006/08/07

最近の投稿

You should never have two classes with the same name in the same classloader. It is unpredictable which one gets loaded. Within a webapp you can put the overriding class in WEB-INF/classes because the spec states that it is loaded before WEB-INF/lib but the same doesn't apply to tomcat's common classloader. What you should do is give it a different name and use that class in your jsp.

If you want to change the implementation of a service then you should extend the class you are overriding and configure spring to use your class.
Guido Kaltwasser
RE: Tomcat 6.x classloader issue
2008/10/13 2:13
答え

Guido Kaltwasser

ランク: New Member

投稿: 18

参加年月日: 2008/09/15

最近の投稿

Hi Mika,

thanks for your reply, since we don't tend to customise to many classes for the core application, we dicided to customise the original class, so that it fits our needs. We do that for convenience. The drawback is obviously that we have to put a bit more effort into merging the customised classes when upgrading to the next version.

Cheers Guido
Karl Mozurkewich
RE: Tomcat 6.x classloader issue
2011/02/12 15:47
答え

Karl Mozurkewich

ランク: New Member

投稿: 10

参加年月日: 2009/02/02

最近の投稿

I ran into this same problem - odd thing was my code worked on a 32bit machine but not a 64bit one.(different jvm obviously) My issue is that I thought the whole idea of the ext-plugin architecture was to allow us to override the LR classes by laying our code on-top of the vanilla LR build during the EXT deployment and registration.

The classes I overrode were core LR interfaces related to search, and as they are used all over the place it would be tedious to go through and update all the existing portlets with new references and prototypes.(men use vi, not IDEs.. emoticon )
Karl Mozurkewich
RE: Tomcat 6.x classloader issue
2011/02/11 13:36
答え

Karl Mozurkewich

ランク: New Member

投稿: 10

参加年月日: 2009/02/02

最近の投稿

Mika Koivisto:
You should never have two classes with the same name in the same classloader.



This is not practical, and not even followed in the LR core. There are multiple instances in the LR trunk where there are disparate classes with the same name. (BooleanQuery.java is an example - both in LR and lucene.jar)
Joel Peterson
RE: Tomcat 6.x classloader issue
2011/02/11 15:04
答え

Joel Peterson

ランク: New Member

投稿: 22

参加年月日: 2010/02/18

最近の投稿

Karl,
I ran into this classloading issue awhile back. I found either a forum or blog post that explained that while the PortalClassLoader loads alphabetically, allowing you to load ext-impl.jar before portal-impl.jar, the app server's class loader was not guaranteed to load the same way. Since portal-service.jar and ext-service.jar deploy to the app server's library folder and not the portal web app's library folder this would explain why it will not always overwrite portal-service.jar.

I would suggest looking at Liferay's spring files to see if you can overwrite Liferay's search beans with your own. All of the Liferay APIs that I have looked at call a spring bean to actually execute the service, so if you were to replace the underlying spring bean definition with your own then you would not necessarily need to update all of their portlets. You can find a bunch of their spring files inside of portal-impl.jar in the META-INF folder.
Mathieu Hicauber
RE: Tomcat 6.x classloader issue
2013/01/23 8:00
答え

Mathieu Hicauber

ランク: Junior Member

投稿: 79

参加年月日: 2010/12/22

最近の投稿

Hi,

I had the problem recently :
- overriding a class from the "Service" part (ThemeDisplay.java)
- a classloader behavior different on my local machine and on the integration machine.

Found a workaround : http://mathieuhicauber-java.blogspot.fr/2012/11/classloader-issue-when-overriding.html

Hope this help.

Mathieu.