2

如果我在 servlet 中使用 ODataQueryBuilder,我可以毫无问题地调用 servlet。

如果我将代码合并到一个方法中并在 ServletContextListener 中调用此方法,我首先会收到以下错误。

2018 02 27 13:17:09#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/]##anonymous#fs-watcher#na#afc186d33#firstapp#web##na#na#na#na#Exception sending context initialized event to listener instance of class com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListenerjava.lang.IllegalStateException: Another strategy was already registered.
at com.netflix.hystrix.strategy.HystrixPlugins.registerConcurrencyStrategy(HystrixPlugins.java:190)
at com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListener.bootstrap(ScpNeoHystrixBootstrapListener.java:43)
at com.sap.cloud.sdk.frameworks.hystrix.ScpNeoHystrixBootstrapListener.contextInitialized(ScpNeoHystrixBootstrapListener.java:74)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5110)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5633)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1015)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:991)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.eclipse.gemini.web.tomcat.internal.TomcatServletContainer.startWebApplication(TomcatServletContainer.java:125)
at org.eclipse.gemini.web.internal.StandardWebApplication.start(StandardWebApplication.java:109)
at org.eclipse.gemini.web.extender.WebContainerBundleCustomizer.addingBundle(WebContainerBundleCustomizer.java:49)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:467)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:443)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEventPrivileged(Framework.java:1568)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1504)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1499)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:391)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:300)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:292)
at org.eclipse.virgo.web.war.deployer.WARDeployer.start(WARDeployer.java:780)
at org.eclipse.virgo.nano.deployer.internal.StandardApplicationDeployer.startDeployables(StandardApplicationDeployer.java:325)
at org.eclipse.virgo.nano.deployer.internal.StandardApplicationDeployer.bulkDeploy(StandardApplicationDeployer.java:116)
at org.eclipse.virgo.nano.deployer.hot.HotDeploymentFileSystemListener.bulkDeployIfNotDeployed(HotDeployerFileSystemListener.java:143)
at org.eclipse.virgo.nano.deployer.hot.HotDeploymentFileSystemListener.onInitialEvent(HotDeployerFileSystemListener.java:105)
at org.eclipse.virgo.util.io.FileSystemChecker.notifyListenersOnInitialEvent(FileSystemChecker.java:207)
at org.eclipse.virgo.util.io.FileSystemChecker.handleInitialFiles(FileSystemChecker.java:177)
at org.eclipse.virgo.util.io.FileSystemChecker.check(FileSystemChecker.java:261)
at org.eclipse.virgo.nano.deployer.hot.WatchTask.run(WatchTask.java:49)
at java.lang.Thread.run(Thread.java:807)

其次是:

  • 一个或多个侦听器无法启动。完整的详细信息将在相应的容器日志文件中找到
  • 由于先前的错误,Context [] 启动失败

这将破坏我的 Servlet 上下文侦听器,然后无法在 NEO 中启动 Web 应用程序。

这很奇怪,因为该方法调用得很好,并且在日志中我可以看到该方法被调用而没有错误。

如果我不在代码中调用该方法,则应用程序启动良好。

请告诉我,我该如何解决这个问题,因为我需要调用 S/4 Hana 系统。

4

1 回答 1

1

更新:

SAP S/4HANA Cloud SDK 2.0.0 版改变了RequestContextListeners 的初始化方式。现在可以使用以下代码而无需额外的努力:

new RequestContextExecutor().execute(...);

原答案:

我猜你想在一些不是由用户请求触发的后台任务中运行逻辑。

您可以尝试将调用 S/4HANA 系统的逻辑包装在 Callable 中,该 Callable 传递给RequestContextExecutor的 execute 方法吗?

例如:

List<SomeData> result = new RequestContextExecutor()
    .execute(new Callable<List<SomeData>>() {
        @Override
        public List<SomeData> call() {
            return new GetSomeDataCommand().execute();
        }
    });

请注意,这将需要在目标配置中具有基本凭据的技术用户;在这种情况下,主传播不可用。

另请注意,如果要ServletContextListener在应用程序启动期间运行调用外部系统的后台任务,则必须

  • 或者显式注册RequestContextListener也是子类的相关类ServletContextListener(包括,如果您使用 SAP Cloud Platform Neo 环境,则初始化ScpNeoHystrixBootstrapListener),
  • 或在文件ServletContextListener中明确指定类的顺序。web.xml

您可以按如下方式显式注册这些侦听器:

// ensure that the correct HystrixConcurrencyStrategy is used
new ScpNeoHystrixBootstrapListener().bootstrap();

// explicitly register RequestContextListeners
new RequestContextExecutor().withListeners(
    new DestinationsRequestContextListener(),
    new ScpNeoDestinationsRequestContextListener(),
    new TenantRequestContextListener(),
    new UserRequestContextListener()
).execute( /* callable */ );
于 2018-02-28T16:08:36.467 回答