سؤال

I'm trying to implement SpringMVC + Quercus as described at http://blog.caucho.com/2009/04/14/using-php-as-a-spring-mvc-view-via-quercus/ .

So I setup Spring like this:

web.xml

<servlet>
        <servlet-name>Quercus Servlet</servlet-name>
        <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
        <init-param>
            <param-name>ini-file</param-name>
            <param-value>WEB-INF/php.ini</param-value>
        </init-param>
    </servlet>

<servlet-mapping>
        <servlet-name>Quercus Servlet</servlet-name>
        <url-pattern>*.php</url-pattern>
    </servlet-mapping>

dispatcher-servlet.xml

<bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/themes/eyitope/"
          p:suffix=".jsp"/>

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="ignoreAcceptHeader" value="true" />
        <property name="mediaTypes">
            <map>
                <entry key="php" value="application/php" />
            </map>
        </property>
        <property name="viewResolvers">
            <list> 
                <!-- used to handle all files with .php extension -->
                <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
                    <property name="viewClass" value="com.caucho.spring.quercus.QuercusView"/>
                    <property name="order" value="1"/>
                    <property name="prefix" value="/WEB-INF/themes/php/"/>
                    <property name="suffix" value=".php"/>
                </bean>
            </list>
        </property>

        <!-- If a compatible view cannot be supplied by the
            ViewResolver chain, then the list of views specified through the DefaultViews property will be
            consulted.
        -->
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            </list>
        </property>
    </bean>

I have a simple controller like this:

@Controller
@RequestMapping("account/*")
public class AccountController {

  public AccountController() {}

  @RequestMapping("signup")
    public String signupTestHandler() {
        return "signup";
    }

}

QuercusView looks like this:

package com.caucho.spring.quercus;

import java.io.*;
import java.util.*;
import java.util.logging.*;

import javax.servlet.*;
import javax.servlet.http.*;

import com.caucho.quercus.*;
import com.caucho.quercus.env.*;
import com.caucho.quercus.module.*;
import com.caucho.quercus.page.*;

import com.caucho.util.L10N;
import com.caucho.vfs.*;

import org.springframework.web.servlet.*;
import org.springframework.web.servlet.view.*;

public class QuercusView
  extends AbstractUrlBasedView
{
  private static final L10N L = new L10N(QuercusView.class);

  private static final Logger log
    = Logger.getLogger(QuercusView.class.getName());

  protected QuercusContext _quercus;
  protected ServletContext _servletContext;

  public QuercusView()
  {
    super();
  }

        protected void initServletContext(ServletContext servletContext)
  {
    _servletContext = servletContext;

    checkServletAPIVersion();

    getQuercus().setPwd(new FilePath(_servletContext.getRealPath("/")));

    getQuercus().init();
  }

  protected void checkServletAPIVersion()
  {
    int major = _servletContext.getMajorVersion();
    int minor = _servletContext.getMinorVersion();

    if (major < 2 || major == 2 && minor < 4)
      throw new QuercusRuntimeException(L.l("Quercus requires Servlet API 2.4+."));
  }

  protected void renderMergedOutputModel(Map model,
                                         HttpServletRequest request,
                                         HttpServletResponse response)
    throws Exception
  {
    Env env = null;
    WriteStream ws = null;

    try {
      Path path = getPath(request);

      QuercusPage page;

      try {
        page = getQuercus().parse(path);
      }
      catch (FileNotFoundException ex) {
        // php/2001
        log.log(Level.FINER, ex.toString(), ex);

        response.sendError(HttpServletResponse.SC_NOT_FOUND);

        return;
      }

      StreamImpl out;

      try {
        out = new VfsStream(null, response.getOutputStream());
      }
      catch (IllegalStateException e) {
        WriterStreamImpl writer = new WriterStreamImpl();
        writer.setWriter(response.getWriter());

        out = writer;
      }

      ws = new WriteStream(out);

      ws.setNewlineString("\n");

      QuercusContext quercus = getQuercus();
      quercus.setServletContext(_servletContext);

      env = quercus.createEnv(page, ws, request, response);

      // retro... thanks, Spring
      for (Object entryObj : model.entrySet()) {
        Map.Entry entry = (Map.Entry) entryObj;
        env.setScriptGlobal((String) entry.getKey(), entry.getValue());
      }

      try {
        env.start();

        env.setScriptGlobal("request", request);
        env.setScriptGlobal("response", response);
        env.setScriptGlobal("servletContext", _servletContext);

        StringValue prepend
          = quercus.getIniValue("auto_prepend_file").toStringValue(env);
        if (prepend.length() > 0) {
          Path prependPath = env.lookup(prepend);

          if (prependPath == null)
            env.error(L.l("auto_prepend_file '{0}' not found.", prepend));
          else {
            QuercusPage prependPage = getQuercus().parse(prependPath);
            prependPage.executeTop(env);
          }
        }

        env.executeTop();

        StringValue append
          = quercus.getIniValue("auto_append_file").toStringValue(env);
        if (append.length() > 0) {
          Path appendPath = env.lookup(append);

          if (appendPath == null)
            env.error(L.l("auto_append_file '{0}' not found.", append));
          else {
            QuercusPage appendPage = getQuercus().parse(appendPath);
            appendPage.executeTop(env);
          }
        }
        //   return;
      }
      catch (QuercusExitException e) {
        throw e;
      }
      catch (QuercusErrorException e) {
        throw e;
      }
      catch (QuercusLineRuntimeException e) {
        log.log(Level.FINE, e.toString(), e);

      //  return;
      }
      catch (QuercusValueException e) {
        log.log(Level.FINE, e.toString(), e);

        ws.println(e.toString());

      //  return;
      }
      catch (Throwable e) {
        if (response.isCommitted())
          e.printStackTrace(ws.getPrintWriter());

        ws = null;

        throw e;
      }
      finally {
        if (env != null)
          env.close();

        // don't want a flush for a thrown exception
        if (ws != null)
          ws.close();
      }
    }
    catch (QuercusDieException e) {
      // normal exit
      log.log(Level.FINE, e.toString(), e);
    }
    catch (QuercusExitException e) {
      // normal exit
      log.log(Level.FINER, e.toString(), e);
    }
    catch (QuercusErrorException e) {
      // error exit
      log.log(Level.FINE, e.toString(), e);
    }
    catch (RuntimeException e) {
      throw e;
    }
    catch (Throwable e) {
      throw new ServletException(e);
    }
  }

  Path getPath(HttpServletRequest req)
  {
    String scriptPath = getUrl();
    String pathInfo = QuercusRequestAdapter.getPagePathInfo(req);

    Path pwd = new FilePath(System.getProperty("user.dir"));

    Path path = pwd.lookup(req.getRealPath(scriptPath));

    if (path.isFile())
      return path;

    // XXX: include

    String fullPath;
    if (pathInfo != null)
      fullPath = scriptPath + pathInfo;
    else
      fullPath = scriptPath;

    return pwd.lookup(req.getRealPath(fullPath));
  }

  /**
   * Returns the Quercus instance.
   */
  protected QuercusContext getQuercus()
  {
    synchronized (this) {
      if (_quercus == null)
        _quercus = new QuercusContext();
    }

    return _quercus;
  }

  /**
   * Gets the script manager.
   */
  public void destroy()
  {
    _quercus.close();
  }

}

Signup.php

<?php
echo 'This is php in Java with SpringMVC as the controller having a php based view resolver called QuercusView. Awesome!';

?>

When I access the resource at /account/signup , I get the following exception

exception

org.springframework.web.util.NestedServletException: Request
processing failed; nested exception is java.lang.NullPointerException
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:681)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:574)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

root cause

java.lang.NullPointerException
        com.caucho.quercus.QuercusContext.getCurrentTime(QuercusContext.java:265)
        com.caucho.quercus.env.Env.start(Env.java:1073)
        com.caucho.spring.quercus.QuercusView.renderMergedOutputModel(QuercusView.java:140)
        org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
        org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
        org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
        org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:574)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

I'm using Tomcat + openejb + Spring3 as EJB container.

Thanks for helping out.

Please I don't know a lot about the inner workings of SpringMVC and Quercus, but I'm hoping someone can help me with some pointers about how to resolve this.

Thanks for helping out.

Edit

The only fishy entry in server startup log is:

INFO: OpenJPA dynamically loaded a validation provider.
[LazyStopWebappClassLoader@5981f6b] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
Dec 7, 2012 4:37:49 AM org.apache.catalina.util.LifecycleBase start
INFO: The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]] after start() had already been called. The second call will be ignored.
[LazyStopWebappClassLoader@5981f6b] error can't determine implemented interfaces of missing type javax.cache.Cache
when weaving type com.caucho.quercus.QuercusContext
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[LazyStopWebappClassLoader@5981f6b] error can't determine implemented interfaces of missing type com.google.appengine.api.users.UserService
when weaving type com.caucho.quercus.lib.gae.GaeUserService
when weaving classes 
when weaving 
 [Xlint:cantFindType]
هل كانت مفيدة؟

المحلول

work copy https://github.com/PaulWeb/TestJavaPhp Stanle was right maybe old version but they forgot to add start

protected QuercusContext getQuercus()
  {
    synchronized (this) {
      if (this._quercus == null) {
        this._quercus = new QuercusContext();
         this._quercus.start();
      }
    }
    return this._quercus;
  }

and if you want to pass from java to php then you have to use env.setGlobalValue

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top