解决NoSuchMethodException: org.apache.myfaces.webapp.filter.TomahawkFacesContextFactory.()问题。

【系统配置简述】

weblogic版本:weblogic12.2.1.3.0

Myfaces:2.3.2

SpringBoot: 1.5.13.RELEASE

Spring: 4.3.17.RELEASE

jdk: Java HotSpot(TM) 64-Bit Server VM 1.8.0_60
 

该war包在STS开发平台(内置Tomcat 8.5.31)下是能正常运行。

【异常】

weblogic部署应用war包时,部署失败,后台日志报异常,Caused by内容如下:

Caused By: java.lang.NoSuchMethodException: org.apache.myfaces.webapp.filter.TomahawkFacesContextFactory.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	at javax.faces.FactoryFinderInstance.getImplGivenPreviousImpl(FactoryFinderInstance.java:407)
	at javax.faces.FactoryFinderInstance.getImplementationInstance(FactoryFinderInstance.java:272)
	at javax.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:549)
	at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:283)
	at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:328)
	at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:236)
	at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:439)
	at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:227)
	at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:705)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
	at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
	at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
	at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
	at weblogic.servlet.internal.EventsManager.executeContextListener(EventsManager.java:251)
	at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:204)
	at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:192)
	at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1921)
	at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3101)
	at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1843)
	at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:884)
	at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
	at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
	at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
	at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)
	at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
	at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:233)
	at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:228)
	at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
	at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:78)
	at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:52)
	at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:752)
	at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
	at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:262)
	at weblogic.application.internal.SingleModuleDeployment.activate(SingleModuleDeployment.java:52)
	at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:165)
	at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:90)
	at weblogic.deploy.internal.targetserver.operations.AbstractOperation.activate(AbstractOperation.java:631)
	at weblogic.deploy.internal.targetserver.operations.ActivateOperation.activateDeployment(ActivateOperation.java:171)
	at weblogic.deploy.internal.targetserver.operations.ActivateOperation.doCommit(ActivateOperation.java:121)
	at weblogic.deploy.internal.targetserver.operations.AbstractOperation.commit(AbstractOperation.java:348)
	at weblogic.deploy.internal.targetserver.DeploymentManager.handleDeploymentCommit(DeploymentManager.java:907)
	at weblogic.deploy.internal.targetserver.DeploymentManager.activateDeploymentList(DeploymentManager.java:1468)
	at weblogic.deploy.internal.targetserver.DeploymentManager.handleCommit(DeploymentManager.java:459)
	at weblogic.deploy.internal.targetserver.DeploymentServiceDispatcher.commit(DeploymentServiceDispatcher.java:181)
	at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.doCommitCallback(DeploymentReceiverCallbackDeliverer.java:217)
	at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.access$100(DeploymentReceiverCallbackDeliverer.java:14)
	at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer$2.run(DeploymentReceiverCallbackDeliverer.java:69)
	at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:670)
	at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)
	at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)
	at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)
	at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
	at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:644)
	at weblogic.work.ExecuteThread.execute(ExecuteThread.java:415)
	at weblogic.work.ExecuteThread.run(ExecuteThread.java:355)

【分析】

TomahawkFacesContextFactory这个类从1.1.7版本开始,但一直都没有init方法,为什么会报找不到init方法呢?

根据异常栈,看了一下Class源码:

private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
                                        int which) throws NoSuchMethodException
    {
        Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
        for (Constructor<T> constructor : constructors) {
            if (arrayContentsEq(parameterTypes,
                                constructor.getParameterTypes())) {
                return getReflectionFactory().copyConstructor(constructor);
            }
        }
        throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
    }

说明没有找到构造方法,为什么呢?stackoverflow类似的问题是这么解决的:
    
The message java.lang.NoSuchMethodException: userAuth.User.<init>() means that someone tried to call a constructor without any parameters. Adding a default constructor should solve this problem:

public class User {

    public User() {

    }

    ..
}

但是,TomahawkFacesContextFactory是有定义构造方法的:

    public TomahawkFacesContextFactory(FacesContextFactory delegate) {
        this.delegate = delegate;
    }

感觉应该是版本问题,于是,换了一个思路,去核对相应的版本。

我发现,myfaces 2.3.2 是2018年8月29日发布,而我使用的weblogic 12c (12.2.1.3.0)  是2017年8月发布。

于是,查了MyFaces 官方文档,MyFaces 2.3需要JSF2.3,servlet 4.0支持。不过挺奇怪的是,本地Tomcat8.5.31对应的servlet是3.1,为什么没有问题呢?估计跟tomcat-embed-jasper的支持有关。

再查weblogic官方文档,发现weblogic12.2.1.3.0仅支持JSF2.2和servlet3.1。问题终于找到,看来是系统选用Myfaces版本太高导致。

那得找Myfaces哪一个版本呢?于是往下查找,找到2.2版本,再到Myface对应的Github上,找到2.2.X中最大的一个版本2.2.12。

【解决】

于是,把Myfaces版本调低至2.2.12,最终问题得到解决。

改起来相对比较简单,直接修改pom.xml文件即可。

<properties>
	……
	<myfaces.version>2.2.12</myfaces.version>
</properties>

文章结束。

猜你喜欢

转载自blog.csdn.net/cysunc/article/details/85251076
今日推荐