Mantis Bugtracker
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0002657 [Quercus] major always 05-09-08 14:59 05-29-08 19:29
Reporter skleinjung View Status public  
Assigned To ferg
Priority normal Resolution fixed  
Status closed   Product Version 3.1.6
Summary 0002657: PHP foreach fails when iterating over a Java list: java.lang.InstantiationException
Description The JavaListAdapter's copy() method is implemented by retrieving the Java class of the underlying list object and calling the newInstance method of that class. This operation fails if the list implementation does not have an accessible no-arg constructor, which is the case for many standard List implementations such as java.util.Collections.UnmodifiableRandomAccessList and java.util.Arrays.ArrayList.
Because the ForeachStatement's execute method uses the Value's copy implementation, attempts to iterate over these list types using foreach fails. The stack trace for this failure is included in the Additional Information section of this report.

I am attaching a war file that illustrates this issue. Deploy it to Resin version 3.1.6 and load it's index.php page to see the error.
Additional Information com.caucho.quercus.QuercusRuntimeException: java.lang.InstantiationException: java.util.Collections$UnmodifiableRandomAccessList
        at com.caucho.quercus.env.JavaListAdapter.copy(JavaListAdapter.java:255)
        at com.caucho.quercus.program.ForeachStatement.execute(ForeachStatement.java:87)
        at com.caucho.quercus.program.BlockStatement.execute(BlockStatement.java:105)
        at com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:272)
        at com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:70)
        at com.caucho.quercus.page.QuercusPage.executeTop(QuercusPage.java:119)
        at com.caucho.quercus.servlet.ResinQuercusServlet.service(ResinQuercusServlet.java:149)
        at com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:355)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:91)
        at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103)
        at com.partslogistics.web.servlet.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:27)
        at com.partslogistics.web.servlet.OpenSessionInViewFilter$$FastClassByCGLIB$$71be6d7d.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
        at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:696)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)
        at com.partslogistics.web.servlet.OpenSessionInViewFilter$$EnhancerByCGLIB$$7e85867f.doFilter(<generated>)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:183)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:138)
        at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87)
        at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187)
        at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:266)
        at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:270)
        at com.caucho.server.port.TcpConnection.run(TcpConnection.java:678)
        at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:721)
        at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:643)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.InstantiationException: java.util.Collections$UnmodifiableRandomAccessList
        at java.lang.Class.newInstance0(Class.java:340)
        at java.lang.Class.newInstance(Class.java:308)
        at com.caucho.quercus.env.JavaListAdapter.copy(JavaListAdapter.java:248)
        ... 28 more
Attached Files  list-bug.war [^] (891 bytes) 05-09-08 14:59
 JavaListAdapter.class [^] (5,717 bytes) 05-09-08 15:04

- Relationships

- Notes
(0003040)
skleinjung
05-09-08 15:04

In order to fix this issue, the copy method of JavaListAdapter needs to use a different method of instantiating the copy. One possibility is to simply use a pre-selected list implementation. This is done by replacing line 248 of com.caucho.quercus.env.JavaListAdapter with something like the following:

List list = new java.util.ArrayList();

I am successfully using this as a workaround for my application for the time being. However, I do not have enough information about how Quercus is implemented to know if this is a safe general-purpose solution or not. I am, however, attaching a patched version of the JavaListAdapter class file in case anyone else with this problem wants to try it as well.
 

- Issue History
Date Modified Username Field Change
05-09-08 14:59 skleinjung New Issue
05-09-08 14:59 skleinjung File Added: list-bug.war
05-09-08 14:59 skleinjung Issue Monitored: skleinjung
05-09-08 15:04 skleinjung Note Added: 0003040
05-09-08 15:04 skleinjung File Added: JavaListAdapter.class
05-29-08 19:29 ferg Assigned To  => ferg
05-29-08 19:29 ferg Status new => closed
05-29-08 19:29 ferg Resolution open => fixed
05-29-08 19:29 ferg Fixed in Version  => 3.2.0


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
32 total queries executed.
26 unique queries executed.
Powered by Mantis Bugtracker