0

我开始将一个 wep 应用程序从 Tomcat 6 更新到当前版本的 Tomcat (7-27)。当我使用以下错误消息启动服务器时出现问题:

错误生命周期 - 无法启动对象 org.gatein.pc.portlet.container.PortletInitializationException:无法使用类 com.qnamic.railopt.web.security.portlet.PortletSecurityFilter 创建过滤器,因为它没有实现预期的接口 javax.portlet.filter。 PortletFilter 在 org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(ClassInstanceLifeCycle.java:85) 在 org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144) 在 org. gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle.java:66) 在 org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93) 在 org.gatein.pc。 portlet.impl.container.PortletApplicationLifeCycle.startDependents(PortletApplicationLifeCycle.java:339) 在 org.gatein.pc.portlet.impl.container.LifeCycle。managedStart(LifeCycle.java:129) 在 org.gatein.pc.mc.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153) 在 org.gatein.pc.mc.PortletApplicationDeployer.add(PortletApplicationDeployer.java:216) 在 org.gatein .pc.mc.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:185) at org.gatein.wci.impl.DefaultServletContainer.safeFireEvent(DefaultServletContainer.java:200) at org.gatein.wci.impl.DefaultServletContainer.fireEvent(DefaultServletContainer.java :219) 在 org.gatein.wci.impl.DefaultServletContainer$RegistrationImpl.registerWebApp(DefaultServletContainer.java:338) 在 org.gatein.wci 的 org.gatein.wci.impl.DefaultServletContainer.access$400(DefaultServletContainer.java:60) .tomcat.TC7ServletContainerContext.start(TC7ServletContainerContext.java:380) 在 org.gatein.wci.tomcat。TC7ServletContainerContext.lifecycleEvent(TC7ServletContainerContext.java:234) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) at org .apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401) 在 org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:168) 在 org.apache.catalina.core.ContainerBase$StartChild.call (ContainerBase.java:1566) 在 org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 在 java. util.concurrent.FutureTask.run(FutureTask.java:138) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent。ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) A: S: R: U: ERROR LifeCycle - 无法启动对象 org.gatein.pc.portlet.container .PortletInitializationException:无法使用类 com.qnamic.railopt.web.core.portal.ContextFilter 创建过滤器,因为它没有在 org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle 实现预期的接口 javax.portlet.filter.PortletFilter .create(ClassInstanceLifeCycle.java:85) at org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144) at org.gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle .java:66) 在 org.gatein.pc.portlet.impl.container.PortletApplicationLifeCycle 的 org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93)。startDependents(PortletApplicationLifeCycle.java:339) at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:129) at org.gatein.pc.mc.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153)在 org.gatein.pc.mc.PortletApplicationDeployer.add(PortletApplicationDeployer.java:216) 在 org.gatein.pc.mc.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:185) 在 org.gatein.wci.impl.DefaultServletContainer.safeFireEvent (DefaultServletContainer.java:200) 在 org.gatein.wci.impl.DefaultServletContainer.fireEvent(DefaultServletContainer.java:219) 在 org.gatein.wci.impl.DefaultServletContainer.access$400(DefaultServletContainer.java:60) 在 org.gatein org.gatein.wci 中的 .wci.impl.DefaultServletContainer$RegistrationImpl.registerWebApp(DefaultServletContainer.java:338)。tomcat.TC7ServletContainerContext.start(TC7ServletContainerContext.java:380) at org.gatein.wci.tomcat.TC7ServletContainerContext.lifecycleEvent(TC7ServletContainerContext.java:234) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)在 org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) 在 org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401) 在 org.apache.catalina.util.LifecycleBase.start (LifecycleBase.java:168) 在 org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566) 在 org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556) 在java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 在 java.util.concurrent.FutureTask.run(FutureTask.java:138) 在 java.util。concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 在 java.lang.Thread.run(Thread.java:619)

com.qnamic.railopt.web.security.portlet.PortletSecurityFilter 类确实实现了接口 javax.portlet.filter.PortletFilter:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Principal;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.EventFilter;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.portlet.filter.ResourceFilter;

import org.apache.log4j.Logger;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class PortletSecurityFilter implements ActionFilter, EventFilter, RenderFilter, ResourceFilter {

ActionFilter 确实实现了 javax.portlet.filter.PortletFilter

依赖的罐子是:

  • primefaces-3.2.jar
  • spring-core-3.0.5.RELEASE.jar
  • spring-asm-3.0.5.RELEASE.jar
  • spring-context-3.0.5.RELEASE.jar
  • spring-aop-3.0.5.RELEASE.jar
  • spring-expression-3.0.5.RELEASE.jar
  • spring-webmvc-portlet-3.0.5.RELEASE.jar
  • spring-webmvc-3.0.5.RELEASE.jar
  • spring-context-support-3.0.5.RELEASE.jar
  • portlet-api-2.0.jar
  • Platform-3.8.0.jar
  • jdo-2.0.jar
  • kodo-runtime.jar
  • openjpa-1.0-fast.jar
  • PlanOpt-3.8.0.jar
  • RailOptBase-3.8.0.jar
  • portletfaces-bridge-api-2.0.0-RC1.jar
  • portletfaces-bridge-impl-2.0.0-RC1.jar
  • portletfaces-logging-1.1.0.jar
  • commons-collections-3.2.1.jar
  • spring-web-3.0.5.RELEASE.jar
  • aopalliance-1.0.jar
  • spring-beans-3.0.5.RELEASE.jar
  • spring-security-web-3.0.5.RELEASE.jar
  • spring-security-core-3.0.5.RELEASE.jar
  • spring-tx-3.0.3.RELEASE.jar
  • aspectjrt-1.6.8.jar
  • aspectjweaver-1.6.8.jar
  • spring-security-config-3.0.5.RELEASE.jar
  • log4j-1.2.15.jar
  • el-api-1.0.jar
  • slf4j-api-1.5.8.jar
  • servlet-api-2.5.jar
  • jstl-1.2.jar
  • commons-lang-2.5.jar
  • RailOptIntegration-3.8.0.jar
  • google-collections-1.0.jar
  • junit-4.8.2.jar
  • commons-io-2.0.1.jar
  • el-impl-2.2.jar
  • javax.faces-2.1.7.jar

一些依赖项具有“提供”的范围,并且不包括在战争中(只要tomcat不使用它们)!

我的 portlet.xml 的一部分

<filter>
<filter-name>PortletSecurityFilter</filter-name>
        <filter-class>com.qnamic.railopt.web.security.portlet.PortletSecurityFilter</filter- class>
    <lifecycle>ACTION_PHASE</lifecycle>
    <lifecycle>EVENT_PHASE</lifecycle>
    <lifecycle>RENDER_PHASE</lifecycle>
    <lifecycle>RESOURCE_PHASE</lifecycle>
    <init-param>
        <name>message</name>
        <value>Security Filter</value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>PortletSecurityFilter</filter-name>
    <portlet-name>*</portlet-name>
</filter-mapping>

其他依赖项位于父项目中:

  • pc-api-2.2.0-GA.jar
  • pc-controller-2.2.0-GA.jar
  • pc-portlet-2.2.0-GA.jar
  • pc-mc-2.2.0-GA.jar
  • wci-wci-2.1.1-GA.jar
  • wci-tomcat7-2.1.1-GA.jar

当我在 org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(...) 中调试代码时,它停在第二行

Class clazz = classLoader.loadClass(className);
if (expectedClass.isAssignableFrom(clazz)) {
    Class<? extends T> castedClass = clazz.asSubclass(expectedClass);
    Constructor<? extends T> ctor = castedClass.getConstructor();
    instance = ctor.newInstance();
}
else  {
    String msg = "Cannot create " + type + " with class " + className + " because it does not   implement the expected interface " + expectedClass.getName();
    throw new PortletInitializationException(msg);
}

我的建议首先是类加载器存在问题,但它不应该是,因为第一行正确加载了类 PortletSecurityFilter。正如预期的那样,预期的类是 javax.portlet.filter.PortletFilter。为什么这个类是不可分配的?

我感谢任何帮助!

4

1 回答 1

1

我必须承认,我不知道您用来解决此问题的 GateIn 的确切版本是什么,但无论如何我可以通过简单地保留(故意)portlet-api-2.0 来使用 GateIn-3.2.0.Final-tomcat7 重现此问题.jar 在我的 war 文件的 WEB-INF/lib 目录中。然后我可以得到类似的东西:

28 janv. 2013 15:48:09 org.gatein.common.logging.Logger log
GRAVE: Cannot start object
org.gatein.pc.portlet.container.PortletInitializationException: Cannot create filter with class org.exoplatform.tutorial.portlet.MyPortletFilter because it does not implement the expected interface javax.portlet.filter.PortletFilter
    at org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(ClassInstanceLifeCycle.java:85)
    at org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144)
    at org.gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle.java:66)
    at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93)
    at org.gatein.pc.portlet.impl.container.PortletApplicationLifeCycle.startDependents(PortletApplicationLifeCycle.java:339)
    at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:129)
    at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153)
    at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.add(PortletApplicationDeployer.java:199)
    at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:168)
    at org.gatein.wci.impl.DefaultServletContainer.safeFireEvent(DefaultServletContainer.java:200)
    at org.gatein.wci.impl.DefaultServletContainer.addWebAppListener(DefaultServletContainer.java:166)
    at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.start(PortletApplicationDeployer.java:241)
    at org.exoplatform.portal.pc.ExoKernelIntegration.start(ExoKernelIntegration.java:178)
    at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.exoplatform.container.LifecycleVisitor.traverse(LifecycleVisitor.java:100)
    at org.exoplatform.container.LifecycleVisitor.start(LifecycleVisitor.java:170)
    at org.exoplatform.container.ConcurrentPicoContainer.start(ConcurrentPicoContainer.java:554)
    at org.exoplatform.container.ExoContainer.start(ExoContainer.java:266)
    at org.exoplatform.container.PortalContainer.start(PortalContainer.java:667)
    at org.exoplatform.container.ExoContainer.start(ExoContainer.java:254)
    at org.exoplatform.container.RootContainer.createPortalContainer(RootContainer.java:399)
    at org.exoplatform.container.RootContainer.registerPortalContainer(RootContainer.java:266)
    at org.exoplatform.portal.application.PortalController.afterInit(PortalController.java:114)
    at org.exoplatform.container.web.AbstractHttpServlet.init(AbstractHttpServlet.java:79)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1201)

我可以通过简单地从我的 webapp 的 WEB-INF/lib 中删除 portlet-api-2.0.jar 来修复它(或者在提供的 maven 中定义这个依赖项)。发生这种情况仅仅是因为 jar 文件已经在 tomcat/lib 中,所以 Portlet Container 引用了从 Tomcat 的公共 ClassLoader 加载的类 javax.portlet.filter.PortletFilter,而您的 Filter 实现了类 javax.portlet.filter。 PortletFilter 已从您的 webapp 的 ClassLoader 加载(来自 WEB-INF/lib),即使这 2 个类的 FQN 相等,它们也不被视为相同的类,这就是为什么 expectedClass.isAssignableFrom(clazz)返回假。

于 2013-01-28T15:34:24.640 回答