2008/11/18 12:53 | 웹개발

현재 Velocity Tools의 최신 버전은 1.4 입니다. 그런데 스트럿츠2에서 1.4 버전을 사용하게 설정을 하면 제대로 되지 않고

java.lang.NoSuchMethodError: org.apache.velocity.tools.view.context.ChainedContext.<init>(Lorg/apache/velocity/context/Context;Ljavax/servlet/http/HttpServletRequest;
Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/ServletContext;)V
       org.apache.struts2.views.velocity.VelocityManager.createContext(VelocityManager.java:193)
       org.apache.struts2.dispatcher.VelocityResult.createContext(VelocityResult.java:235)
       org.apache.struts2.dispatcher.VelocityResult.doExecute(VelocityResult.java:152)
       org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:178)
       com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:348)
       com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:253)
       ...


이런 류의 오류가 발생합니다.

원인은 스트럿츠2가 이 전 버전에 포함돼 있고 이제는 지원이 중단된 생성자를 사용하고 있기 때문입니다. 이를 해결하기 위해서는 다음과 같은 자신만의 VelocityManager 클래스를 만든 후 이를 사용하게 스트럿츠2에 등록해 주면 됩니다.

import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.VelocityStrutsUtil;
import org.apache.struts2.views.jsp.ui.OgnlTool;
import org.apache.struts2.views.util.ContextUtil;
import org.apache.struts2.views.velocity.StrutsVelocityContext;
import org.apache.struts2.views.velocity.VelocityManager;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.context.ChainedContext;

import com.opensymphony.xwork2.util.ValueStack;

public class MyVelocityManager extends VelocityManager
{

            private static final Logger LOG = Logger.getLogger(MyVelocityManager.class);

            public Context createContext(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
                VelocityContext[] chainedContexts = prepareChainedContexts(req, res, stack.getContext());
                StrutsVelocityContext context = new StrutsVelocityContext(chainedContexts, stack);
                Map standardMap = ContextUtil.getStandardContext(stack, req, res);
                for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext();) {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    context.put((String) entry.getKey(), entry.getValue());
                }
        context.put(STRUTS, new VelocityStrutsUtil(getVelocityEngine(), context, stack, req, res));

                ServletContext ctx = null;
                try {
                    ctx = ServletActionContext.getServletContext();
                } catch (NullPointerException npe) {
                    // in case this was used outside the lifecycle of struts servlet
                    LOG.debug("internal toolbox context ignored");
                }

                if (toolboxManager != null && ctx != null) {

                    // here is the new constructor :
                    ChainedContext chained = new ChainedContext(getVelocityEngine(), req, res, ctx);

                    chained.setToolbox(toolboxManager.getToolbox(chained));
                    return chained;
                } else {
                    return context;
                }

            }
}


스트럿츠2에 등록은

struts.xml 에
<constant name="struts.velocity.manager.classname" value="com.mypackage.MyVelocityManager" ?>

또는,

struts.properties 에
struts.velocity.manager.classname=com.nate.santorini.framework
.SantoriniVelocityManager

라고 해 주면 됩니다.

이 내용은 Struts2 & Velocity Tools 에서 찾을 수 있었습니다.
2008/11/18 12:53 2008/11/18 12:53
Trackback Address :: http://dream.ahboom.net/trackback/18