WSO2 API Manager 4.2.0动态费率订阅无法查看发票问题求助
问题描述
已成功配置Stripe与WSO2 API Manager账户关联,为API创建动态费率订阅并完成绑定,API monetization设置完成,通过Postman发送使用数据正常。但尝试查看发票时,弹出窗口显示:
No Data Available
Pending invoice data not found for this subscription
同时后台抛出如下错误:
ERROR - GlobalThrowableMapper An unknown exception has been captured by the global exception mapper. java.lang.NoSuchMethodError: 'org.wso2.carbon.apimgt.api.model.APIIdentifier org.wso2.carbon.apimgt.api.model.SubscribedAPI.getApiId()' at org.wso2.apim.monetization.impl.StripeMonetizationImpl.getCurrentUsageForSubscription(StripeMonetizationImpl.java:1285) ~[org.wso2.apim.monetization.impl-1.4.1.jar:?] at org.wso2.carbon.apimgt.rest.api.store.v1.impl.SubscriptionsApiServiceImpl.subscriptionsSubscriptionIdUsageGet(SubscriptionsApiServiceImpl.java:478) ~[?:?] at org.wso2.carbon.apimgt.rest.api.store.v1.SubscriptionsApi.subscriptionsSubscriptionIdUsageGet(SubscriptionsApi.java:188) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?] at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?] at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[?:?] at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[?:?] at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[?:?] at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[?:?] at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[?:?] at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[?:?] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) ~[?:?] at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[?:?] at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[?:?] at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[?:?] at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[?:?] at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[?:?] at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[?:?] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:304) ~[?:?] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:222) ~[?:?] at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) ~[tomcat-servlet-api_9.0.76.wso2v1.jar:?] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:279) ~[?:?] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat_9.0.76.wso2v1.jar:?] at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:119) ~[org.wso2.carbon.identity.context.rewrite.valve_1.7.1.jar:?] at org.wso2.carbon.identity.context.rewrite.valve.OrganizationContextRewriteValve.invoke(OrganizationContextRewriteValve.java:116) ~[org.wso2.carbon.identity.context.rewrite.valve_1.7.1.jar:?] at org.wso2.carbon.tomcat.ext.valves.SameSiteCookieValve.invoke(SameSiteCookieValve.java:38) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:165) ~[org.wso2.carbon.identity.authz.valve_1.7.1.jar:?] at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:118) ~[org.wso2.carbon.identity.auth.valve_1.7.1.2.jar:?] at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:106) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:67) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:152) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:673) ~[tomcat_9.0.76.wso2v1.jar:?] at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:63) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:137) ~[org.wso2.carbon.tomcat.ext_4.8.1.jar:?] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat_9.0.76.wso2v1.jar:?] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat_9.0.76.wso2v1.jar:?] at java.lang.Thread.run(Thread.java:833) [?:?]
切换至WSO2 API Manager 4.1.0版本后,问题消失,现需找到适配4.2.0版本的解决方案。
问题原因
错误核心是NoSuchMethodError,说明org.wso2.apim.monetization.impl-1.4.1.jar中调用的SubscribedAPI.getApiId()方法在APIM 4.2.0的org.wso2.carbon.apimgt.api.model.SubscribedAPI类中已不存在或方法签名变更,属于组件版本不兼容问题。APIM 4.2.0对核心API模型做了调整,而当前使用的Stripe monetization实现包仍依赖旧版本的API方法。
解决方案
1. 升级Stripe Monetization组件至兼容版本
替换<APIM_HOME>/repository/components/dropins或<APIM_HOME>/repository/components/plugins目录下的org.wso2.apim.monetization.impl-*.jar为适配APIM 4.2.0的版本,重启APIM服务后验证发票查看功能。
2. 修复Monetization实现代码(自定义场景)
若无法获取官方兼容包,可手动修改StripeMonetizationImpl.java:
- 定位到第1285行调用
subscribedAPI.getApiId()的位置,替换为APIM 4.2.0中SubscribedAPI类对应的方法(如getAPIIdentifier(),需确认实际方法名)。 - 重新编译打包jar文件,替换原文件后重启服务。
3. 清理缓存确保生效
删除APIM安装目录下的<APIM_HOME>/tmp和<APIM_HOME>/work目录,清除Tomcat缓存,避免旧类加载冲突。
4. 验证数据完整性
- 检查APIM数据库中
AM_SUBSCRIPTION、AM_USAGE_DATA等表是否存在对应订阅的使用记录。 - 确认Stripe后台是否同步到对应的订阅和使用数据,排除数据同步异常导致的无数据问题。
内容的提问来源于stack exchange,提问作者CHAROUNI

