Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
Showing 1 - 20 of 26 results.
of 2
Pete Helgren
java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 3, 2013 3:15 PM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

I have seen a few posts like this but no solution that works. I have a services portlet that was generated using the service builder. The services*.jar that was created resides ONLY in the Tomcat_home/lib/ext folder and nowhere else. I have another portlet which accesses the services*.jar

Running the LR 6.0.6 Tomcat bundle on Windows 7 JDK 1.6.0_13. Full stack trace is:

SEVERE: Servlet.service() for servlet LectureManagerServlet threw exception
java.lang.ClassCastException: $Proxy251 cannot be cast to org.bsfinternational.in.central.service.persistence.LectureRecordingPersistenceImpl
at org.bsfinternational.in.central.service.impl.LectureRecordingLocalServiceImpl.getLectureRecording(LectureRecordingLocalServiceImpl.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:44)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy266.getLectureRecording(Unknown Source)
at org.bsfinternational.in.central.service.LectureRecordingLocalServiceUtil.getLectureRecording(Unknown Source)
at org.bsfinternational.filemgr.LectureManagerServletInteraction.execAccessLecture(LectureManagerServletInteraction.java:264)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.niggle.servlet.NiggleConfig.dispatchAction(NiggleConfig.java:249)
at org.niggle.servlet.ServletInteraction.dispatch(ServletInteraction.java:423)
at org.niggle.servlet.NiggleServlet.doPost(NiggleServlet.java:100)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)

Why is this failing? I get the same failure with the Glassfish bundle with the same LR version on Windows 7. Can anyone give me the basics on how to troubleshoot this?

Thanks
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 6, 2013 6:10 PM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

This represents a failure in your plugin that is providing the service, not an external portlet (since the service jar does not have any of the actual implementation details).

Can you show us what you have at LectureRecordingLocalServiceImpl.java:120?
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 7, 2013 8:22 AM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks David. I think I am closer to understanding the issue after wrestling with it over the weekend. The 'trigger' on all of this is that we are moving from using Netbeans to Eclipse and the move hasn't been smooth for many different reasons (we started with changing too many things like target server: Glassfish to Tomcat, LR version 6.0.6 to 6.1.1, so on). Going back to just Eclipse IDE and GF 3.0.1 bundle for LR 6.0.6, through quite a bit of trial an error we are down to just this $Proxy issue. Here is what I am seeing:

In the WAR that is generated by Netbeans I see this kind of class structure in the classes folder in WEB-INF:

<package path>.model
<package path>.service
And in the package root I see a series of 'NoSuch.....Exception.class' files.

In the Eclipse generated WAR I see:
<package path>.model
<package path>.service
But NO 'NoSuch...Exception.class' files. In fact there are no class files in the <package path> root folder at all.

Navigating to the <package path>.model. folder in the Netbeans WAR I see the following:
<package path>.model.impl (a folder)
And in the <package path>.model root folder there are a bunch of class files that correspond to the services generated. For example the first entry in services.xml is for AppConfig. I see these in the <package path>.model. package root:

AppConfig.class
AppConfigClp.class
AppConfigModel.class
AppConfigWrapper.class
......

There are many classes in this folder (<package path>.model ) but NONE of them exist in the Eclipse generated WAR. The <package path>.model folder in the Eclipse generated WAR is empty except for an 'impl' folder.

So I think what is causing the error is that the jar contains entries that the deployed portlet does not have. There is something in the ant build that is not correctly building the correct war structure in Eclipse or I am not building the war correctly. Classes are missing in some of the folders in the deployed war file and it appears to follow the pattern above. The Netbeans generated war is OK and deploys correctly. The Eclipse generated war is missing classes (like those above) for the exact same services (using the same services.xml).

So now I think I know the cause, how to I track down what is wrong in the building of the war in Eclipse?

Thanks again,

Pete
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 7, 2013 8:41 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

Okay, NB vs Eclipse aside, SB code has a pretty standard layout:

In your plugin, docroot/WEB-INF is where all of the code lives. In this folder is the service.xml file where your entities are defined.

When you use ant to run service builder, docroot/WEB-INF/service and docroot/WEB-INF/src will get populated with java source files, xml files, ...

The docroot/WEB-INF/service directory contains the entity POJO interfaces, the XxxLocalServiceUtil classes, the class loader proxy stuff, and the NoSuchXxxException classes, but none of the implementation classes (i.e. the persistence classes, the XxxLocalServiceImpl classes, the model implementation classes, etc.).

The docroot/WEB-INF/src directory contains all of the implementation classes. The persistence classes are here, the model implementation classes, the service implementation classes, the finders, etc.

During the project build, the docroot/WEB-INF/service directory contents get compiled into the service jar. This is the jar that needs to be shared with external plugins to make the service available to them.

The docroot/WEB-INF/src directory contents get compiled into docroot/WEB-INF/classes directory of the plugin project. These classes are not copied, shared, or relocated anywhere. They are just used by the plugin itself to provide the services.

Okay, now all of that being said, based upon what you've indicated it sounds like perhaps NB was not keeping these things separate (either accidentally or purposely based upon your configuration).

I'd suggest actually starting over, kind of... In the SDK, create a new plugin from scratch. Copy your service.xml to the docroot/WEB-INF directory of your new plugin. Build the services (using ant) to recreate all of the source files. This will give you the correct directory structure where all of the files need to live for everything to be correct.

Then copy the files from your old NB project to the new plugin, but this time make sure that the files are dropped into the appropriate place (either the docroot/WEB-INF/src or docroot/WEB-INF/service directory).

This should clean up all of your issues...
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 7, 2013 2:26 PM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks again David. So, just so I am clear, are those "missing" classes really missing? Or, are you saying that they are an artifact of a NB configuration error? I can actually generate the same class structure in the deployed portlet if I include the service folder as a source folder on the build path. But, it sounds like those 'extra' classes are only generated in the .jar and not the war for the deployed portlet. Do I have that correct? IOW those classes I identified in the NB war aren't necessary and are a red herring in this case?

FYI. This started as a scratch project in Eclipse and the only thing that was copied from the NB project was the service.xml. So I assumed that Eclipse was generating everything correctly. It wasn't until I compared the structure of the NB generated war and the Eclipse generated war that I saw the difference in structure and started to second guess my settings.

So, if Eclipse is generating the war and jar correctly, then back to your original question: What is at line 120 when the proxy error occurs? It is the following:

LectureRecordingPersistenceImpl persistence = (LectureRecordingPersistenceImpl)lectureRecordingPersistence;

It is part of this method:

public LectureRecording getLectureRecording(int classNumber, Date lectureDate) throws com.liferay.portal.kernel.exception.SystemException
{
List<LectureRecording> recordingList = null;
if (lectureDate == null)
{
LectureRecordingPersistenceImpl persistence = (LectureRecordingPersistenceImpl)lectureRecordingPersistence;
Session session = null;
try
{
session = persistence.openSession();
Query query = session.createQuery("SELECT lectureRecording_ "
+ " FROM LectureRecording lectureRecording_ "
+ " WHERE Number = " + classNumber
+ " AND Lecture_Date IN (SELECT MAX(l_.lectureDate) "
+ " FROM LectureRecording l_"
+ " WHERE Number = " + classNumber
+ ")"
+ " ORDER BY Lecture_Recording_ID DESC");
recordingList = query.list();
}
finally
{
persistence.closeSession(session);
}
}
else
recordingList = lectureRecordingPersistence.findByClassNumberAndLectureDate(classNumber, lectureDate);

return recordingList == null || recordingList.isEmpty() ? null : recordingList.get(0);
}

I hope that points to something useful.

Pete
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 8, 2013 5:38 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

Eclipse has the correct structure, so stick with what it generated.

Line 120 is wrong, you don't need to cast to a persistence impl class, you can just use the interface.

Try "lectureRecordingPersistence.openSession();" itself and all should be fine.
Jelmer Kuperus
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 8, 2013 5:55 AM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

Basically what David says. And you should probably be creating a custom finder. That's a lot nicer than what you are doing
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 8, 2013 10:01 AM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks again. lectureRecordingPersistence doesn't have an openSession() method. I think that is why the developer cast the class to the ...Impl class.

Not sure how to fix this since the query needs a session object to create the query. Perhaps this is what was meant in the other post about using a custom finder as a better solution?

The other "odd" thing here is that this code is basically unmodified from the version that was created using Netbeans. The relevant modified java files were added after the service builder was run in Eclipse (the service/impl files)

So basically it was:
Create a new project in Eclipse
Create a new Liferay service builder in the project
Copy the services.xml from Netbeans to Eclipse
Build the services
Copy the java files from the 'service/impl' folder in the Netbeans project to the same folder in the Eclipse project
Build the services
Deploy the war

Outside of the differences in war structure that I mentioned before, there were no other modifications needed in the java files (some xml files were added or changed to accommodate resource references). The Netbeans generated war and service jar works fine when deployed to LR. When we deploy the Eclipse generated war, we encountered this error so I am a little uncertain how this worked before if indeed it is a coding issue.
Jelmer Kuperus
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 8, 2013 2:17 PM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

Your generated LectureRecordingPersistence interface should extend from com.liferay.portal.service.persistence.BasePersistence which has the openSession method in there. So it should be there. If you can't find the method in your ide then portal-service.jar is probably not on your classpath
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 9, 2013 7:25 AM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks Jelmer. I have to admit that I am still getting my feet on the ground when it comes to the framework here. David suggested that I use the lectureRecordingPersistence interface which doesn't have the method (as mentioned). As I did more research, I DID find that BasePersistence has the openSession() method but that is in LR 6.1.1. I am using 6.0.6.

Is there another way to get the persistence session without a cast to the *.Impl class here? I know you mentioned a "better way" of accomplishing what this method does (you suggested a custom finder) but is there another way to handle this other than using a custom finder?

Thanks
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 9, 2013 10:19 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

I also am using LR 6.0.6, and I can use xxxPersistence.openSession() to get a session object...

Actually I'm still concerned about the class cast exception. This will occur when you actually have a class loader conflict. Did you by chance copy the service jar from either the NB or E projects to tomcat's lib/ext directory?

The class loader in tomcat should allow you to have the same class in two projects (as long as the class doesn't get loaded from the global class loader).

Oh, and do you have both the NB and E plugins deployed at the same time? Could there be some sort of mix and match failure, i.e. you're using the service jar from the NB project to access the service plugin that was built from the E project?
Jelmer Kuperus
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 9, 2013 3:02 PM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

I also am using LR 6.0.6, and I can use xxxPersistence.openSession() to get a session object...


Doubtful, the openSession method was added to BasePersistence as part of the changes made for LPS-18440

And 18440 is marked as fixed for 6.0.12 EE & 6.1.0 CE RC1. Maybe you are using the enterprise edition ?

One way of getting the session factory is :

1SessionFactory sessionFactory = (SessionFactory) PortalBeanLocatorUtil.locate("liferaySessionFactory");


You can call openSession() on that

But i *STRONGLY* suggest that a custom finder is used to implement this. I don't really see a good reason why not to take this route
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 9, 2013 4:39 PM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

All good questions. I have been concerned about the mix and match as well and I have been very careful to clean up after myself (or at least I think I have). I am fairly certain that I have undeployed the portlets and removed the jars correctly.

The plot thickens a bit because there are two goals here:

1) Move off of NB as the IDE
2) Move from Glassfish bundle of 6.0.6 to Tomcat bundle of 6.0.6

Here is what I see:

The NB created SB war and jar deploys on Glassfish 3.0.1 without a hitch. I also have written a servlet which uses the services in the SB portlet. The ONLY way I can use the services this way is to put the services*.jar in the GF_HOME/domains/domain1/lib folder. With this combination all is well with the NB generated SB portlet and my servlet.

The Eclipse generated SB war when deployed to the same GF instance (having removed the old war and seeing it undeploy in GF) and removing the service*.jar from the GF_HOME/domain/domain1/lib folder and replacing it with the Eclipse generated one, generates the $Proxy error. With Tomcat, well, I can't get Tomcat to work with this kind of configuration regardless of where I put the service*.jar so I have focused for now on GF (I wish I could get it to work with TC but after months of trying I have given up for now)

Just as a reminder I am running LR 6.0.6CE on Windows 7 (64bit) Java 1.6.0_31 (64 bit mixed mode). Both the GF and TC bundles are used.

I suspect that I am either creating the SB portlet incorrectly or that Eclipse is building things slightly differently than NB. If I remove the offending cast in the getLectureRecording member LectureRecordingLocalServiceImpl and just set the session to null, the $Proxy cast exception error goes away but of course I get an NPE instead. If I *could* return a session with an openSession then I could probably get past the error.

Again, this exact same $Proxy cast error occurs both in GF and TC with the Eclipse generated SB portlet. It doesn't occur in GF with the NB generated SB portlet (but the NB generated doesn't work in TC anyway - I always get a BeanLocator has not been set error). For the Eclipse generated SB war/jar in TC, if I only have the service*.jar in the WEB-INF/lib folder of the deployed portlet and the WEB-INF/lib of my servlet then I get a BeanLocator has not been set for servlet context error (yeah, just like with the NB generated SB portlet). As you surmised, the $Proxy cast error occurs when the service*.jar resides in the /lib/ext folder and in the SB portlet's WEB-INF/lib folder.

This may get a bit confusing because of the GF vs TC scenarios along with the NB vs Eclipse scenario. But to summarize:

NB generated SB portlet works with servlet in GF when the jar resides in the ../domain1/lib folder AND the SB portlet's WEB-INF/lib folder.
Eclipse generated SB portlet generates the $Proxy cast error in GF when using the same deployment strategy.

In TC the NB generated SB portlet generates a BeanLocator has not been set for servlet context when the service*.jar is deployed to the servlet WEB-INF/lib and the Portal WEB-INF/lib.
In TC the Eclipse generated portlet generates the $Proxy cast error when the service*.jar resides in the /lib/ext folder and the portlet WEB-INF/lib folder

Probably TMI but I want to be as clear as possible.

Thanks
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 10, 2013 5:54 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

Jelmer's right, I'm using EE so that would explain the availability of openSession() in my persistence interface...

Pete Helgren:
The NB created SB war and jar deploys on Glassfish 3.0.1 without a hitch. I also have written a servlet which uses the services in the SB portlet. The ONLY way I can use the services this way is to put the services*.jar in the GF_HOME/domains/domain1/lib folder. With this combination all is well with the NB generated SB portlet and my servlet.


Okay, this is neither an NB or Eclipse issue, this is just a deployment issue. In both cases, GF and T, you just need to copy the service jar to the WEB-INF/lib directory of the servlet to use the services. You must ensure that the load order has the servlet load after the plugin providing the service loads in the app container, otherwise you'll end up with bean locator exceptions...

The Eclipse generated SB war when deployed to the same GF instance (having removed the old war and seeing it undeploy in GF) and removing the service*.jar from the GF_HOME/domain/domain1/lib folder and replacing it with the Eclipse generated one, generates the $Proxy error. With Tomcat, well, I can't get Tomcat to work with this kind of configuration regardless of where I put the service*.jar so I have focused for now on GF (I wish I could get it to work with TC but after months of trying I have given up for now)


When you are deploying any SB-based service in this manner (promoting service jar to the global loader), you must remove the service jar from the plugin after deployment. You should only have a single instance of the service jar, the one in the global lib dir, and no copies in the web apps folder.

I don't know about NB, but Eclipse relies totally on the SDK/ant build process for bundling and deploying plugins. I know in my SDK directory I've indicated I'm using tomcat for the app server type (in the build-${username}.properties file), but I think that if you're switching between app servers you may need to change your file to build the correct deployment artifact.


Just as a reminder I am running LR 6.0.6CE on Windows 7 (64bit) Java 1.6.0_31 (64 bit mixed mode). Both the GF and TC bundles are used.

I suspect that I am either creating the SB portlet incorrectly or that Eclipse is building things slightly differently than NB.


Well, for the most part Eclipse does not do anything during the build except invoke ant (and therefore the SDK). NB, I'm not sure if it does the same or if it uses a different build process for Liferay.

Again, this exact same $Proxy cast error occurs both in GF and TC with the Eclipse generated SB portlet. It doesn't occur in GF with the NB generated SB portlet (but the NB generated doesn't work in TC anyway - I always get a BeanLocator has not been set error). For the Eclipse generated SB war/jar in TC, if I only have the service*.jar in the WEB-INF/lib folder of the deployed portlet and the WEB-INF/lib of my servlet then I get a BeanLocator has not been set for servlet context error (yeah, just like with the NB generated SB portlet). As you surmised, the $Proxy cast error occurs when the service*.jar resides in the /lib/ext folder and in the SB portlet's WEB-INF/lib folder.


The BeanLocator not being set is load order in the app container. The servlet is trying to access the service before the service is set up and ready to go. Often times for a servlet it may be easier to use the remote service instead of the local service because the bean locator stuff is not invoked.
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 10, 2013 11:50 AM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Some more trial and error and I have the GF server deployment sorted out. Here is what I discovered:

I am now able to deploy either the NB created SB portlet and jar OR the Eclipse created SB portlet but ONLY on Glassfish. After MUCH trial and error, I discovered that the Eclipse created SB portlet had one xml file that was creating the $Proxy cast problem: the 'shard-data-source-spring.xml' file in the /classes/META-INF folder! I have no idea of why this particular XML file created so much trouble but once I deleted it , I could create services and deploy from Eclipse with no problem whatsoever to GF.

For Glassfish - Centralizing the service*.jar in the global lib dir folder will work if I include the util-bridges.jar and the util-java.jar in the SB portlet's WEB-INF/lib folder.

In Tomcat: There really isn't any way to get my servlet to use the SB Portal services. Your recommendation to use only one instance in the global lib dir in Tomcat produces a BeanLocator has not been set error:

com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set
at com.liferay.portal.kernel.bean.PortletBeanLocatorUtil.locate(PortletBeanLocatorUtil.java:40)
at org.bsfinternational.in.central.service.LectureRecordingLocalServiceUtil.getService(LectureRecordingLocalServiceUtil.java:298)
at org.bsfinternational.in.central.service.LectureRecordingLocalServiceUtil.getLectureRecordingByAccessCode(LectureRecordingLocalServiceUtil.java:289)

For some reason, probably because of differences in class and resource loading in GF vs TC, I have never been successful in getting the SB portlet and my servlet to work together in TC. In GF, I now have both the NB and Eclipse generated SB portlet working.

I agree that the issue here is the sequence of loading the classes/contexts necessary to locate the resources for the servlet. I have seen documentation that shows how to add directives that indicate which which jars are required and which contexts have to be loaded first but that is in reference to portlets. In my case I have a servlet that requires a context to be loaded first so I am not sure where I can configure that.

At least I know why I was getting the $Proxy cast error (that pesky 'shard-data-source-spring.xml' file). Solving the context loading issue for TC would be icing on the cake. The long term goal IS to use Tomcat rather than Glassfish, but if I can't access the services in the SB portlet in TC from my servlet , I'm stuck. I haven't yet tried going to 6.1.1 CE but my last attempt resulted in a BeanLocator error. Armed with more knowledge now, I may try again.

Thanks for sticking with this thread David. I know your time is valuable. Your help has been invaluable!

Pete
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 10, 2013 6:34 PM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

Pete Helgren:
In Tomcat: There really isn't any way to get my servlet to use the SB Portal services. Your recommendation to use only one instance in the global lib dir in Tomcat produces a BeanLocator has not been set error:


Yep, this is due to the servlet being loaded/configured before the plugin providing the service has been loaded. It's definitely a timing issue....

Actually I have a utility method that I use to run a task after the bean locator is good to go. Method looks like this:

 1public static void waitForBeanLocator(final String servletContextName, final Runnable task) {
 2  // do not launch a thread if the bean locator is already available
 3  if (PortletBeanLocatorUtil.getBeanLocator(servletContextName) != null) {
 4    task.run();
 5    return;
 6  }
 7
 8  Thread waiter = new Thread() {
 9    public void run() {
10      BeanLocator locator = null;
11
12      do {
13        locator = PortletBeanLocatorUtil.getBeanLocator(servletContextName);
14        if (locator == null) {
15          try { sleep(1000);} catch (InterruptedException e) {}
16        }
17      } while (locator == null);
18
19      task.run();
20    };
21
22    waiter.start();
23  }
24}


Obviously you could alter the code to just do a blocking wait in your code until the bean locator is set and then continue, or whatever. But it gives you an overall idea how to poll for the availability of the bean locator and wait until it's available before using it...
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 11, 2013 7:26 AM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks again. So my assumption jibes with your experience.

At what point in the invocation of the plugin resources do you wait and how often? My ignorance of classloading and visibility is showing here. When my servlet invokes a method from the SB portlet (jar) is it at that point that an attempt is made to locate the bean? The error occurs for me whenever I invoke an SB method regardless of when. I would have thought (and again I am fairly ignorant of the way that servlet classes are loaded by the container) that all of the portal resources are loaded and configured at container start up.

So, for example after the container has started up I invoke a method in my servlet that displays a web page. The user keys in an ID number that is then passed to the SB portlet with a call to a service builder method:

public void execAccessLecture() throws IOException
{
.......
if(!accessCode.equals("none") && !accessCode.equals("default@liferay.com")){
// We need to retrieve the particulars of the record. classID specifically...
try {
lr = LectureRecordingLocalServiceUtil.getLectureRecordingByAccessCode(accessCode); // SB method call
if(lr!=null){
.......

Do you use your "wait" method in the invocation of your servlet methods or in the invocation of the SB portlet's method? Do you have to wrap all of your methods in this way or only on the first invocation?
David H Nebinger
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 11, 2013 8:47 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

Well, each call to a method in LectureRecordingLocalServiceUtil will continuously try to get the service object (you can actually look at the generated source, the LectureRecordingLocalServiceUtil class will have a getService() method which is responsible for getting the service implementation object, it's inside this code where the bean locator exception results).

I had a special case where I needed to do some stuff at startup, hence my looping guy that would wait until the bean locator stuff was good to go before running my logic.

If you were doing the calls to LectureRecordingLocalServiceUtil on demand after the container was available, then the bean locator stuff should have been good to go at that point.

I remember needing to add a portlet.properties file to the servlet even though it had no portlet component, but the invoked bean locator stuff was always looking for it so I added an empty file to satisfy that.

Also my servlet used all of the same jars (copied in, actually) from the ROOT/WEB-INF/lib directory from Liferay. I did this because I wanted to ensure that I wasn't going to end up w/ some class loader conflicts (i.e. different versions of spring or hibernate or whatnot).

It truly is a pain to diagnose and resolve these classpath issues. Unfortunately the bean locator exception is just an indicator that there is something wrong, but does not necessarily point to the source of the problem...
Pete Helgren
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
January 11, 2013 12:50 PM
Answer

Pete Helgren

Rank: Regular Member

Posts: 117

Join Date: April 7, 2011

Recent Posts

Thanks again David, you have been very helpful through this whole process and I have learned a great deal. It is unfortunate that Tomcat and Glassfish don't "act" the same in this instance. Somehow GF is getting all the right resources in the correct places at the right time and Tomcat does not. If I had a trace of the classes loading in GF and then one for Tomcat I could probably sort things out.

I'll chalk it up as a mystery for the moment, I might post this over at the Apache Tomcat forum and see what they might have to say.

Pete
Lijo Daniel
RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to
February 17, 2013 10:03 PM
Answer

Lijo Daniel

Rank: New Member

Posts: 1

Join Date: January 5, 2012

Recent Posts

Hi Pete,
Have you found any solution to this problem? I am also facing the same problem in tomcat. I am using liferay 6.1.

Regards,
Lijo
Showing 1 - 20 of 26 results.
of 2