Foros de discusión

java.lang.ClassCastException: $ProxyXXX cannot be cast to

thumbnail
Pete Helgren, modificado hace 11 años.

java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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?
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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...
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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.
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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.
thumbnail
jelmer kuperus, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 1191 Fecha de incorporación: 10/03/10 Mensajes recientes
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
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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?
thumbnail
jelmer kuperus, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 1191 Fecha de incorporación: 10/03/10 Mensajes recientes
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 :

SessionFactory 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
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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.
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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:

public static void waitForBeanLocator(final String servletContextName, final Runnable task) {
  // do not launch a thread if the bean locator is already available
  if (PortletBeanLocatorUtil.getBeanLocator(servletContextName) != null) {
    task.run();
    return;
  }

  Thread waiter = new Thread() {
    public void run() {
      BeanLocator locator = null;

      do {
        locator = PortletBeanLocatorUtil.getBeanLocator(servletContextName);
        if (locator == null) {
          try { sleep(1000);} catch (InterruptedException e) {}
        }
      } while (locator == null);

      task.run();
    };

    waiter.start();
  }
}


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...
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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?
thumbnail
David H Nebinger, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 14914 Fecha de incorporación: 2/09/06 Mensajes recientes
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...
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
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, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

New Member Mensaje: 1 Fecha de incorporación: 6/01/12 Mensajes recientes
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
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
No I haven't and it is a mystery why the folks at Liferay haven't figured this out. IMHO it is a showstopper for using LR at all. We are limping ahead with LR 6.0.6 and GF for the moment but we are looking to get off the platform because of the many bugs and difficulties in getting the most simple configurations to work. Seems to me that using the services provided by a SB portlet across many other portlets would be a logical design and yet trying to get that to work has been a challenge.

I haven't tried David's last suggestion of copying all the LR jars to the portlet's lib folder. I remember heading down that path because of a similar solution I saw in the forum but it had side effects that I don't recall at the moment but caused problems for me elsewhere.

I'd love to have a solution but nothing so far and no hope in sight.....
thumbnail
jelmer kuperus, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 1191 Fecha de incorporación: 10/03/10 Mensajes recientes
and difficulties in getting the most simple configurations to work


that's because you're stuborn and aren't listening to what i am saying to you emoticon
thumbnail
Pete Helgren, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Regular Member Mensajes: 225 Fecha de incorporación: 7/04/11 Mensajes recientes
So what I am I not listening to? This goes far beyond a custom finder. It affects all services that are provided by a SB portlet. Doesn't make a difference whether it is this particular method is a "finder" or not. SB services cannot be accessed from a servlet in Tomcat, period and yet they can be in Glassfish. That is the issue.
john kammer, modificado hace 10 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

New Member Mensajes: 6 Fecha de incorporación: 1/07/13 Mensajes recientes
Hello Gentlemen,
I've run into a similar problem and found your thread in seeking a resolution. I think my problem is slightly different and I'll describe it as best I can. Unfortunately I am not able to cross-post listing or error traces so forgive/bear with me.

Background: I developed a very simple MVCPortlet using service builder that queries a database returning the text of one field based on a key value. The portlet itself runs fine - I was only using that as a proof of concept. I wanted to create a servlet that uses the services jar created by the Service Bulder. I've copied the myStuff-services.jar file to the tomcat/WEB-INF/lib directory and deleted all other instances of it. I then pointed everything that needed the service classes to this new location. At that point I was able to rid myself of the $ProxyXXX errors - yea, I'm making progress.

Now the problem I am wrestling with is a BeanDefinitionParsingException that indicates a root cause of a ClassNotFound error where the not-found class is one of the implementation classes in the src code (vs. the /service code). I assume (based on your discussion that I'd read) this problem is a result of the order the server is being loaded and Spring not being able to find the classes because they haven't been loaded yet -- I am a Spring novice and that is being generous to myself.

Looking for ways to start Tomcat webapps in the order I would like seems to be an unpromising venture so I am wondering how to handle this.

Would it make sense to jar up the Impl files and put them in Tomcat's WEB-INF/ROOT/lib directory as well? I'll likely give that a try but not sure it'll solve anything or not. Is there a better solution I'm unaware of, or am I doing something wrong here? That would not surprise me as I'm entirely new to service builder and liferay.

FWIF I am using the 6.1 release of Liferay.

Any constructive thoughts on the matter would be appreciated.

Thanks!
john kammer, modificado hace 10 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

New Member Mensajes: 6 Fecha de incorporación: 1/07/13 Mensajes recientes
Hello Gentlemen,
I've run into a similar problem and came across your thread in seeking a resolution. I think my problem is slightly different but reasonably close and I'll describe it as best I can. Unfortunately I am not able to cross-post listing or error traces so forgive/bear with me.

Background: I developed a very simple MVCPortlet using service builder that queries a mysql database returning the text of one field based on a key value in another. The portlet itself runs fine - I was only using that as a proof of concept. I wanted to create a servlet that uses the services jar created by the Service Bulder. I've copied the myStuff-services.jar file to the tomcat/WEB-INF/ROOT/lib directory and deleted all other instances of it. I then pointed everything that needed the service classes to this new location. At that point I was able to rid myself of the $ProxyXXX errors - yay, I'm making progress.

Now the problem I am wrestling with is a BeanDefinitionParsingException that indicates a root cause of a ClassNotFound error where the not-found class is one of the implementation classes in the src code (vs. the /service code). I assume (based on your discussion that I'd read) this problem is a result of the order the server is being loaded and Spring not being able to find the classes because they haven't been loaded yet -- I am a Spring novice and that is a generous description for myself.

Looking for ways to start Tomcat webapps in the order I would like seems to be an unpromising venture so I am wondering how to handle this.

Would it make sense to jar up the Impl files and put them in Tomcat's WEB-INF/ROOT/lib directory as well? I'll likely give that a try but not sure it'll solve anything or not. Is there a better solution I'm unaware of, or am I doing something wrong here? That would not surprise me as I'm entirely new to service builder and liferay.

FWIF I am using the 6.1 release of Liferay.

Any constructive thoughts on the matter would be appreciated.

Thanks!
john kammer, modificado hace 10 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

New Member Mensajes: 6 Fecha de incorporación: 1/07/13 Mensajes recientes
Having given it some thought it seems obvious to me that Tomcat needs to know where the impl classes are, so jaring them up and sticking them in the tomcat/lib directory seems to make sense. It also get rid of a handful of errors.

Moving on a tad I am wrestling with getting the correct liferay/hibernate jars in the right place as well. Seemed to be working well until a "status.jsp" page could not be located in wap/portlet/status.jsp. Checking the directory I verified there was no such file. There was a status.jsp in html/portlet/status.jsp but copying that over to the wap/portlet directory just caused the whole think to belly-up.

Scratching my head at the moment. Not sure where to look. Assuming I've not got the right jar files in the tomcat lib directory.....
thumbnail
jelmer kuperus, modificado hace 11 años.

RE: java.lang.ClassCastException: $ProxyXXX cannot be cast to

Liferay Legend Mensajes: 1191 Fecha de incorporación: 10/03/10 Mensajes recientes
Basically what David says. And you should probably be creating a custom finder. That's a lot nicer than what you are doing