首页 \ 问答 \ 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 ...

相关文章

更多

最新问答

更多
  • 谁有JAVA的视频教程啊 最好从基础开始到精通 打包好的
  • 仅根据表格的一列删除重复的值(Remove duplicate values based on only one column of the table)
  • 从数据库值填充数组的最有效方法?(Most efficient way to populate array from database values?)
  • 我在data属性中有一个变量,并从prop传递相同的变量。(I have one variable in data attribute, and pass the same variable from prop. why the {{}} template display the value from prop rather than data)
  • Reg Ex Django Url Conf(Reg Ex Django Url Conf)
  • 本地化不适用于主要活动(Localization does not work on main activity)
  • 我有一个同学让我去福州科闽计算机学校学习室内设计,这个学校好吗?
  • 变量的模板参数中的Decltype(Decltype in template parameter of variable)
  • 代码签名错误与Xcode 4.2(Code Sign error with Xcode 4.2)
  • 在保留表达式生命周期的同时强制执行参数评估顺序(Enforce parameter evaluation order while retaining lifetime of of expressions)
  • 查询以获取早于开始日期的日期行(不是简单的WHERE)(Query to get date rows older than a start date (not a simple WHERE))
  • 武清哪家会计培训机构通过率高?
  • Java正则表达式逻辑OR(Java regex logical OR)
  • 使用for循环创建异步Vue组件(Use for loop to create async Vue component)
  • 从magento数据库获取客户名称和电子邮件(Get customer names and emails from magento database)
  • 运行Ruby冒泡排序(Running Through a Ruby Bubble Sort)
  • 减去返回多于1行的两个SQL子查询的结果(Subtracting the results of the two SQL subqueries that returns more than 1 row)
  • 对于Ruby http请求,响应“呃?”是间歇性的(The response “er ?” is getting intermittently for Ruby http request)
  • 请问嘉定区有没有培训上海市电脑中级的,有的话在哪里?
  • 根据日期范围查询最小分区键(聚类键)(Query min partition key based on date range (clustering key))
  • int listinsert(sqlist * & L)中的&是什么意思
  • 原始套接字的会话管理(Session Management on Raw Socket)
  • 将Type用作“属性”是不好的做法?(Is it bad practise to use Type as a 'Property'?)
  • 电脑等级证书二级和三级有什么区别啊 !!我们学校有二级和三级培训到底该选着那个呢????????
  • linux 安装新硬盘如何设置权限
  • 无法从RecyclerView的onBindViewHolder更改根视图的大小或位置(Cannot change root view's size or position from RecyclerView's onBindViewHolder)
  • spin.js没出现在我的网站上?(spin.js is not showing up on my site?)
  • Gulp + Bootstrap字体(Gulp + Bootstrap Fonts)
  • 如何使用短信Alfresco.util.PopupManager.displayPrompt显示图标(How to show icon with text message Alfresco.util.PopupManager.displayPrompt)
  • Skype.getAllChats()未检测到基于云的群组聊天(Skype.getAllChats() not detecting cloud-based group chats)