2

TomEE で JSF プロジェクトを実行しています。MyFace 2.1.8 にアップグレードしました。Oracle JVM 1.7.04を使用してOSXですべてを実行しています

だから私はViewScopedであるこのManagedBeanを持っています:

@ManagedBean
@ViewScoped
public class BlogMB implements Serializable {
    private static final long serialVersionUID = 1L;
    @EJB
    private CategoryService categoryService;
}

ビューコードは次のとおりです。

<h:commandLink value="#{category.name}">
    <f:setPropertyActionListener
        target="#{blogMB.selectedCategory}"
        value="#{category}" />
    <f:ajax
        listener="#{blogMB.filterPostsByCategory()}"
        execute="@this"
        render=":blogPosts" />
</h:commandLink>

このスタック トレースの結果。一体何が起こっているのですか?ハンドルを逆シリアル化する必要があることはわかっていますが、クラスパスでサービス クラスを見つけるのに問題があるのはなぜですか?

Jul 06, 2012 8:25:51 PM org.apache.myfaces.renderkit.ServerSideStateCacheImpl deserializeView
SEVERE: Exiting deserializeView - Could not deserialize state: com.xxx.blog.service.CategoryService
java.lang.ClassNotFoundException: com.xxx.blog.service.CategoryService
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at java.io.ObjectInputStream.resolveProxyClass(ObjectInputStream.java:694)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1549)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1511)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at java.util.HashMap.readObject(HashMap.java:1043)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1685)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1341)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at java.util.HashMap.readObject(HashMap.java:1043)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1685)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1341)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.deserializeView(ServerSideStateCacheImpl.java:497)
    at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.getSerializedViewFromServletSession(ServerSideStateCacheImpl.java:289)
    at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.restoreSerializedView(ServerSideStateCacheImpl.java:891)
    at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getState(HtmlResponseStateManager.java:205)
    at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.restoreView(DefaultFaceletsStateManagementStrategy.java:207)
    at org.apache.myfaces.application.StateManagerImpl.restoreView(StateManagerImpl.java:130)
    at org.apache.myfaces.shared.view.ViewDeclarationLanguageBase.restoreView(ViewDeclarationLanguageBase.java:106)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.restoreView(FaceletViewDeclarationLanguage.java:2109)
    at org.apache.myfaces.application.ViewHandlerImpl.restoreView(ViewHandlerImpl.java:300)
    at com.ocpsoft.pretty.faces.application.PrettyViewHandler.restoreView(PrettyViewHandler.java:109)
    at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:83)
    at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:127)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.omnifaces.filter.GzipResponseFilter.doFilter(GzipResponseFilter.java:147)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:75)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

編集の更新:

記録されたチケットhttps://issues.apache.org/jira/browse/MYFACES-3581

4

2 に答える 2

3

deserializeViewMyFacesでメソッドにパッチを適用する必要があるようです。簡単に言うと、ObjectInputStreamはスレッドコンテキストClassLoader(Thread.currentThread().getClassLoader())を使用しません。したがって、この種の「適切なクラスローダーを使用してください。修正はアプリサーバーで非常に普及しています。MyFacesが含まれている場合WEB-INF/lib/、これは魔法のようになくなります。これは、MyFacesと逆シリアル化されるクラスが同じクラスローダーに含まれるためです。ただし、MyFacesを移動することは正しい修正ではありません。パッチを当てた方がいいです。

デシリアライズを実行するクラスが親クラスローダーにあり、したがって多数の子クラスローダー(各Webアプリに1つ)からのクラスを表示できない場合、通常は次のようにする必要があります。

import java.io.*;
import java.lang.reflect.Proxy;

public class SmarterObjectInputStream extends ObjectInputStream {

    public SmarterObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
        try {
            return Class.forName(classDesc.getName(), false, getClassloader());
        } catch (ClassNotFoundException e) {
            String n = classDesc.getName();
            if (n.equals("boolean")) return boolean.class;
            if (n.equals("byte")) return byte.class;
            if (n.equals("char")) return char.class;
            if (n.equals("short")) return short.class;
            if (n.equals("int")) return int.class;
            if (n.equals("long")) return long.class;
            if (n.equals("float")) return float.class;
            if (n.equals("double")) return double.class;

            throw e;
        }
    }

    protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
        Class[] cinterfaces = new Class[interfaces.length];
        for (int i = 0; i < interfaces.length; i++)
            cinterfaces[i] = getClassloader().loadClass(interfaces[i]);

        try {
            return Proxy.getProxyClass(getClassloader(), cinterfaces);
        } catch (IllegalArgumentException e) {
            throw new ClassNotFoundException(null, e);
        }
    }

    private ClassLoader getClassloader() {
        return Thread.currentThread().getContextClassLoader();
    }
}

MyFacesにこれを与えSmarterObjectInputStream、メソッドで使用するようにする必要がありますdeserializeView

パッチを適用することの栄誉が必要な場合、それは素晴らしいことであり、MyFacesはTomEEユーザーが修正を提供しているのを見るのに非常に熱心になると確信しています。これまでにいくつかの素晴らしい貢献がありました!

于 2012-07-07T02:39:51.350 に答える
0

考えられる回避策は、web.xml で次のように設定することです。

<context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
</context-param>

ただし、これはかなり非標準であり、私はこれをテストしていません。

于 2012-07-16T16:14:34.333 に答える