首页 \ 问答 \ Reactor - 在flatMap的输出上调用块会导致ClassCastException(Reactor - Calling block on output of flatMap causes ClassCastException)

Reactor - 在flatMap的输出上调用块会导致ClassCastException(Reactor - Calling block on output of flatMap causes ClassCastException)

我正在使用Spring Boot 2.0.0.M7和Project Reactor。 我的问题涉及编写单元测试时遇到的一些奇怪的行为。 在尝试将flatMap的输出提供给存储库时,我也遇到了这个问题。

Mono<Foo> create(Mono<FooResource> resourceMono) {
    resourceMono.flatMap({
        // convert resource into Foo domain Entity
        return new Foo()
    })
}

由于flatMap的返回值,这个闭包应该发出一个Mono<Foo> 。 但是,在调用block()来订阅并获取生成的FooFluxFlatMap.trySubscribeScalarMap存在ClassCastException

测试代码:

   def createdFoo = Foo.create(Mono.just(fooResource)).block() 

堆栈跟踪:

java.lang.ClassCastException: com.example.Foo cannot be cast to org.reactivestreams.Publisher

at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:141)
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53)
at reactor.core.publisher.Mono.block(Mono.java:1161)

这似乎是因为MonoJust实现了Callable而发生的,所以trySubscribeScalarMap尝试解包失败。

在非测试案例场景中,会发生类似的错误。

Mono<ServerResponse> createFoo(ServerRequest request) {
    def body = request.body(BodyExtractors.toMono(FooResource))
    ok().body(fromPublisher(Foo.create(body)
        .flatMap({fooRepository.save(it)}), Foo))
}

堆栈跟踪:

java.lang.ClassCastException: com.example.Foo cannot be cast to reactor.core.publisher.Mono
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) [reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1092) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
<...>
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.flatMap(Mono.java:2059)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrap.invoke(PojoMetaMethodSite.java:213)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
com.example.Foo.create(Foo.groovy:28)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
com.example.FooHandlerFunctions.createFoo(FooHandlerFunctions.groovy:48)

在另一个Mono.just(foo)封装flatMap闭包的输出解决了这两个问题。 但是,这似乎不应该需要。 我做错了什么或者误解了flatMap在这里的工作原理?


I'm using Spring Boot 2.0.0.M7 and Project Reactor. My issue is relating to some strange behavior encountered while writing a Unit test. I also ran into this while trying to feed the output of flatMap into the repository.

Mono<Foo> create(Mono<FooResource> resourceMono) {
    resourceMono.flatMap({
        // convert resource into Foo domain Entity
        return new Foo()
    })
}

This closure should emit a Mono<Foo> due to the return value of flatMap. However, when calling block() to subscribe and get the resulting Foo, there is a ClassCastException in FluxFlatMap.trySubscribeScalarMap

Test code:

   def createdFoo = Foo.create(Mono.just(fooResource)).block() 

Stack Trace:

java.lang.ClassCastException: com.example.Foo cannot be cast to org.reactivestreams.Publisher

at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:141)
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53)
at reactor.core.publisher.Mono.block(Mono.java:1161)

This appears to occur because MonoJust implements Callable, so trySubscribeScalarMap tries to unwrap it unsuccessfully.

In a non-test case scenario, a similar error occurs.

Mono<ServerResponse> createFoo(ServerRequest request) {
    def body = request.body(BodyExtractors.toMono(FooResource))
    ok().body(fromPublisher(Foo.create(body)
        .flatMap({fooRepository.save(it)}), Foo))
}

Stack trace:

java.lang.ClassCastException: com.example.Foo cannot be cast to reactor.core.publisher.Mono
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) [reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1092) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE]
<...>
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.flatMap(Mono.java:2059)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrap.invoke(PojoMetaMethodSite.java:213)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
com.example.Foo.create(Foo.groovy:28)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
com.example.FooHandlerFunctions.createFoo(FooHandlerFunctions.groovy:48)

Wrapping the output of the flatMap closure in another Mono.just(foo) solves both issues. However, it seems like that shouldn't be needed. Am I doing something wrong or just misunderstanding how flatMap works here?


原文:https://stackoverflow.com/questions/47994303
更新时间:2024-03-14 11:03

最满意答案

当然有办法做到这一点! 天无绝人之路!

任何人,我认为你正在寻找的是远程服务器。 这取决于你有多少钱可以用几种方法完成。

(1)如果你一直都像我一样摔断,那么你可以在家中制作一台额外的电脑,作为你的应用程序的服务器。 尽管如此,这可能会导致几个(:) hehe几个)安全问题。 您的家庭网络上也会有很多流量。

(2)它是获得域名和虚拟主机的另一种选择。 我见过的大多数网络托管服务都提供数据库支持。 所以你可以做的是跳上,在Web主机服务器上创建你的数据库,然后将你的应用程序链接到你的服务器。 其成本因您的需求而异。

真的,是你的应用程序与多个人交互? 我想不出你会希望在任何其他电话(设备)上使用此功能的原因,而不是(相对于我们的客户)设备。 我很少将设备交给其他人,除非锁定,否则绝不会。


Of course there is way to do it! There is always a way!

Anywho, what I think you are looking for is a remote server. These can be done in a few way depending on how much money you have.

(1)If you're broke like me all the time, then you can make an extra computer you have at home act as a server for your app. This can cause a few ( :) hehe few) security issues for your home though. Also you will have a lot of traffic on your home network.

(2)Another option it's to get a domain name and web host. Most of the web hosting services I have seen offer database support. So what you could do is hop on, create your database on the web host server then link your app to your server. The cost on that varies based on your needs.

Really though, is your app interfacing with mulitple people? I can't think of a reason you would want this feature on any other phone (device) than your (relative to us customers) device. I rarely hand my device over to others, and never unless it's locked.

相关问答

更多
  • 确保XAMPP中的Apache模块已启动,并且您的Android手机已连接到您的路由器(假设您在无线网络上)。 查找托管服务器的计算机的本地IP地址。 例如,我的是192.168.1.142。 这可能与您的相似也可能不相似。 在手机的URL栏中输入该IP地址。 您可能还需要将端口号附加到该端口号,具体取决于服务器设置。 例如,如果XAMPP在端口8080上运行Apache:192.168.1.142:8080。 要获取本地IP,它会因操作系统而略有不同。 对于Windows,转到命令提示符并执行ipconf ...
  • 当然有办法做到这一点! 天无绝人之路! 任何人,我认为你正在寻找的是远程服务器。 这取决于你有多少钱可以用几种方法完成。 (1)如果你一直都像我一样摔断,那么你可以在家中制作一台额外的电脑,作为你的应用程序的服务器。 尽管如此,这可能会导致几个(:) hehe几个)安全问题。 您的家庭网络上也会有很多流量。 (2)它是获得域名和虚拟主机的另一种选择。 我见过的大多数网络托管服务都提供数据库支持。 所以你可以做的是跳上,在Web主机服务器上创建你的数据库,然后将你的应用程序链接到你的服务器。 其成本因您的需求 ...
  • 注意:我没有足够的声望来发布包含两个以上链接的帖子:/以下所有项目都应该通过网络搜索很容易找到。 收集breakpad崩溃报告是否存在更好的项目? Mozilla的Socorro是Mozilla使用的一个开源项目,用于收集Firefox等应用程序的breakpad崩溃报告。 您可以通过搜索Mozilla崩溃统计信息来查看他们的Socorro实例。 有没有好的托管选项? 我只知道有三家公司提供了托管的breakpad崩溃管理选项:Backtrace I / O,Bugsplat和Raygun I / O。 充 ...
  • 您可能需要更新JAR文件,但为什么在可以使用Gradle获取依赖项时使用JAR文件? dependencies { compile 'com.parse.bolts:bolts-android:1.+' compile 'com.parse:parse-android:1.+' } 此外,Play服务目前是8.4.0 ,除非您确实需要所有 Play服务,否则建议您只选择您真正使用的依赖项 。 You might need to update your JAR files, but why ...
  • 本指南可能比您真正要求的信息更多,但Web服务器信息就在那里。 它是Gentoo特有的,但是您可以将相同的信息与小版本应用到其他发行版。 This guide is probably more info than you really requested, but webserver information is in there. It's Gentoo-specific, but you can apply the same information with minor translations to ...
  • 我在html5中为android和ios开发应用程序,我将在云端托管它,可能是亚马逊。 使用云,您将支付您真正使用的内容。 使用传统托管服务,无论您的应用程序是否被使用,您都需要按年/月支付固定金额。 云是动态的,所以如果您的应用突然变成populuar,您的应用仍然可以正常工作,因为云提供商将提供更多资源。 我试试亚马逊,因为它在一定数量的资源需求下免费。 对于第二个问题,我认为这些api没有问题。 Im developing an app in html5 for android and ios and ...
  • 那么我解决了这个问题,通过我的无线路由器访问我的笔记本电脑的IPv4,并通过它连接到我的服务器的端口。 最初,我的浏览器(我的笔记本电脑和手机)都无法访问服务器的端口。 但后来我发现它是我的.yml配置文件中的问题。 服务器没有设置为监听所有的IPv4呼叫,而是监听所有的IPv6。 所以我改变了这一点,然后就可以在同一个wifi上访问所有设备。 所以把它连接到热点是我的坏主意:P Well I solved this problem by accessing IPv4 of my laptop throug ...
  • 您可以配置 (通过XML或代码)具有特定超时的端点。 这是在servicehost启动时设置的,运行时无法更改。 同样不,客户端无法设置服务超时,因为这会使拒绝服务攻击变得非常容易。 您最好通过隔离“文件上载服务”并相应地配置其端点。 You can configure (throught XML or code) an endpoint with certain timeouts. This is set at servicehost startup and can't be changed while ...
  • 只有在WCF中确保“互操作性”的绑定才是BasicHttpBinding 。 如果您需要最小过载,请不要使用WCF。 编写自己的基于tcp的协议,使用套接字或任何你喜欢的。 这是非常类似问题的答案。 Only binding that assures "interoperability" in WCF is BasicHttpBinding. If you need minimum overload don't use WCF. Write your own tcp based protocol, use ...
  • 将router.Run从router.Run("127.0.0.1:8080")更改为router.Run(":8080")并且它可以正常工作。 正如@elithrar和@ user3591723所建议的那样127.0.0.1(本地主机)只是机器上的环回接口绑定到“:8080”意味着0.0.0.0:8080 - 这意味着所有接口 Changed the router.Run from router.Run("127.0.0.1:8080") to router.Run(":8080") and it wor ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。