I was using iBeacon library version 0.6 and everything was fine except monitoring. In that version monitoring was happening but the monitoring notifier callback was not getting called because library used an "implicit intent" to pass this information.
see Issue IBeacon getting warning Implcit intents are not safe on callback of MonitorNotifier
Recently I upgraded to the version 0.7.6 of the iBeacon android library and it solved the problem of monitoring callback but I found a new issue with this upgrade.
I am getting an Exception which is
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
I am invoking my app'S method inside the ranging notifier callback and If I am wrapping it inside UI thread than that exception is not coming but it slowing down the performance of the app.
here is the code
BackgroundRangingFragment.java
#Override
public void onIBeaconServiceConnect() {
//Ranging Notifier
iBeaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
//If beacon found in the specified Region.
if (iBeacons.size() > 0) {
MainActivity main = (MainActivity)MainActivity.mainActivityInstance;
main.setActiveBeaconsFromBackgroundRangingFragment(iBeacons);
}
}
}
MainActivity.java
public void setActiveBeaconsFromBackgroundRangingFragment(List<Beacon> tempActiveBeaconArrayList){
this.activeBeaconArrayList.clear();
activeBeaconArrayList.addAll(tempActiveBeaconArrayList);
MainRangingFragmennt fragment = (MainRangingFragmennt)getSupportFragmentManager().findFragmentByTag("beaconLogFragment");
if(fragment != null){
fragment.setActiveBeaconListForBeaconLogFromBackgroundRangingData(this.activeBeaconArrayList);
}
MainRangingFragment.java
//Refreshes Beacon log
public void setActiveBeaconListForBeaconLogFromBackgroundRangingData(List<Beacon> activeBeacons){
//Here I am updating view with currently active beacons.
LinearLayout progressBar = (LinearLayout)this.view.findViewById(R.id.beacon_log_list_progress);
progressBar.setVisibility(View.VISIBLE); //This line is raising exception .
//code continues ...
}
Exception message.
04-22 18:10:15.546: E/isNull(1435): MainRangingFragmennt{421408c0 #2 id=0x7f0c0021 beaconLogFragment}
04-22 18:10:15.546: W/dalvikvm(1435): threadid=19: thread exiting with uncaught exception (group=0x4186fba8)
04-22 18:10:15.546: E/AndroidRuntime(1435): FATAL EXCEPTION: IntentService[IBeaconIntentProcessor]
04-22 18:10:15.546: E/AndroidRuntime(1435): Process: com.example.ranging, PID: 1435
04-22 18:10:15.546: E/AndroidRuntime(1435): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.support.v4.widget.DrawerLayout.requestLayout(DrawerLayout.java:762)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.requestLayout(View.java:16431)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.setFlags(View.java:8908)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.view.View.setVisibility(View.java:6036)
04-22 18:10:15.546: E/AndroidRuntime(1435): at com.example.ranging.MainRangingFragmennt.setActiveBeaconListForBeaconLogFromBackgroundRangingData(MainRangingFragmennt.java:309)
04-22 18:10:15.546: E/AndroidRuntime(1435): at com.example.ranging.MainActivity.setActiveBeaconsFromBackgroundRangingFragment(MainActivity.java:497)
04-22 18:10:15.546: E/AndroidRuntime(1435): at com.example.ranging.BackgroundRanging$4.didRangeBeaconsInRegion(BackgroundRanging.java:489)
04-22 18:10:15.546: E/AndroidRuntime(1435): at com.radiusnetworks.ibeacon.IBeaconIntentProcessor.onHandleIntent(IBeaconIntentProcessor.java:73)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.os.Handler.dispatchMessage(Handler.java:102)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.os.Looper.loop(Looper.java:136)
04-22 18:10:15.546: E/AndroidRuntime(1435): at android.os.HandlerThread.run(HandlerThread.java:61)
I am using fragments to load the beacon data in the UI.
When receiving asynchronous calls from the AndroidIBeaconLibrary, you must wrap any code that updates the user interface inside blocks like below:
runOnUiThread(new Runnable() {
public void run() {
...
}
}
This is a general rule for building Android apps, and isn't something that specifically changed from the 0.6 to 0.7.6 version of the Android iBeacon Library. Sometimes thread handling is indeterminate, so it is certainly possible that this happened to work most or all the time in version 0.6. The fact remains is that you need to make sure this processing is run on the UI thread. It should not affect performance.
I think the most likely explanation for why you see a "delay" and some beacons "getting ignored" is because of the way the setActiveBeaconListForBeaconLogFromBackgroundRangingData method is designed. You must write it to take into account the fact that you WILL NOT get a complete list of all visible beacons on every callback. You must maintain a separate list in your UI, and merge in any newly visible iBeacons passed to this method. Likewise, you must programmatically drop off any iBeacons from this list that have not been reported to be visible within a few seconds.
Again, this is not something that specifically changed between the library versions, but I don't doubt that subtle timing differences could make the issue more acute after an upgrade.
Related
stackTrace:
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at okhttp3.internal.http2.Http2Stream.waitForIo(Http2Stream.java:645)
at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.java:151)
- locked <0x00000006f12faee8> (a okhttp3.internal.http2.Http2Stream)
at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.java:136)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.java:115)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:43)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
at okhttp3.RealCall.execute(RealCall.java:81)
version: 3.14.2
Similar feedback:
android - OkHttp ANR at okhttp3.internal.http2.Http2Stream.waitForIo$okhttp(Http2Stream.kt:716) - Stack Overflow
Http2Stream blocked forever 3.6.0 · Issue #3246 · square/okhttp · GitHub
Sometime may block · Issue #4241 · square/okhttp · GitHub
OkHttp3 source code:
/**
* Like {#link #wait}, but throws an {#code InterruptedIOException} when interrupted instead of
* the more awkward {#link InterruptedException}.
*/
void waitForIo() throws InterruptedIOException {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Retain interrupted status.
throw new InterruptedIOException();
}
}
I am working on standalone spring boot application and used spring integration channel architecture to transfer files from source to destination.
We have provided multi-instance feature as well, to achieve this we will be locking(append .lock for the files) files for particular instance to restrict access from other instance.
Currently, I have one requirement for graceful shutdown . I implemented but end-up with the following error. Can anyone help me on this ?
Control bus configuration :
<integration:channel id="controlChannel" />
<integration:control-bus input-channel="controlChannel" />
Adapter configuration :
<file:inbound-channel-adapter id="filesInChannel"
directory="path" auto-startup="false" scanner="recursiveScanner"
auto-create-directory="true">
<integration:poller id="poller"
max-messages-per-poll="5" fixed-rate="1000"
task-executor="pollingExecutor">
<integration:transactional
transaction-manager="transactionManager" />
</integration:poller>
</file:inbound-channel-adapter>
Method added for graceful shutdown component
#PreDestroy
public void onDestroy() throws InterruptedException {
try {
inboundFileAdapterChannel.send(new GenericMessage<String>("#'filesInChannel.adapter'.stop()"));
} catch (Exception e) {
e.printStackTrace();
}
// wait till current processing of files is over
pollingExecutor.shutdown();
pollingExecutor.setWaitForTasksToCompleteOnShutdown(Boolean.TRUE);
System.out.println("Application shutdown succesfully");
}
Error Trace :
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application.controlChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=#'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}], failedMessage=GenericMessage [payload=#'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}]
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
at com.openbank.interfaces.file.handler.GracefulShutdownHook.onDestroy(GracefulShutdownHook.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:365)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeDestroyMethods(InitDestroyAnnotationBeanPostProcessor.java:323)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction(InitDestroyAnnotationBeanPostProcessor.java:155)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:240)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:577)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:549)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:957)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:510)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:964)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1041)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1017)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:937)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=#'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}]
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:138)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
... 19 more
#PreDestroy is too late to perform such operations.
By that time all Lifecyle beans will have been stop()ped (which unsubscribes from the channel).
You need to perform that work using some other signal.
You could implement SmartLifecyle and put your bean in a late phase (so it is stop()ped early.
I have a working application running on Android 6.0 (API 23), but when I try to run it on a Android 4.4 (API 19) I got an unexpected exception during PESDK.init. Something should be missing in my project but I can not figure out what is going on...
The error is generated when trying to call initSensor method in OrientationSensor class as it is shown here :
import ly.img.android.ui.utilities.OrientationSensor;
public static final String VERSION_NAME = "4.1.4"
private static void init() {
OrientationSensor.initSensor(PESDK.getAppContext());
}
The exception log message is :
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at ly.img.android.a.a(Unknown Source)
at ly.img.android.PESDK.init(Unknown Source)
at my.app.MainApplication.onCreate(MainApplication.java:101)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoClassDefFoundError: ly.img.android.ui.utilities.OrientationSensor
at ly.img.android.PESDKInit.init(PESDKInit.java:27)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at ly.img.android.a.a(Unknown Source)
at ly.img.android.PESDK.init(Unknown Source)
at my.app.MainApplication.onCreate(MainApplication.java:101)
These seem to be an issue with your "proguard-rules".
Please check your Settings, Orientation Sensor should not be removed by proguard because it clearly referenced in code.
Please also consider updating to v5.0.15
In Spring 5.0.0.RC4 reference documentation, it said:
Publisher or Flow.Publisher — any type implementing Reactive Streams Publisher is supported.
https://docs.spring.io/spring/docs/5.0.0.RC4/spring-framework-reference/reactive-web.html#webflux
But when I created a simple project based on Spring 5.0.0.RC4, I got failure when return Flow.Publisher in a controller. It seems the Flow.Publisher can not be serialized by jackson.
org.springframework.core.codec.CodecException: Type definition error: [simple type, class java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.concurrent.SubmissionPublisher["executor"]->java.util.concurrent.ForkJoinPool["factory"])
at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:132)
at org.springframework.http.codec.json.AbstractJackson2Encoder.lambda$encode$0(AbstractJackson2Encoder.java:96)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)
at reactor.core.publisher.FluxJust$WeakScalarSubscription.request(FluxJust.java:91)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:156)
at org.springframework.http.server.reactive.ChannelSendOperator$WriteBarrier.onSubscribe(ChannelSendOperator.java:143)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
at reactor.core.publisher.FluxJust.subscribe(FluxJust.java:68)
at reactor.core.publisher.FluxMapFuseable.subscribe(FluxMapFuseable.java:63)
at org.springframework.http.server.reactive.ChannelSendOperator.subscribe(ChannelSendOperator.java:76)
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1068)
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:72)
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:198)
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:198)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1068)
at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onNext(MonoIgnoreThen.java:290)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:1625)
at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onSubscribe(MonoIgnoreThen.java:279)
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:161)
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:148)
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74)
at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74)
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:271)
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:798)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:115)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:1625)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:156)
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:1439)
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:1313)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59)
at reactor.core.publisher.Mono.subscribe(Mono.java:2757)
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:418)
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:210)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:91)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:55)
at reactor.core.publisher.FluxConcatMap.subscribe(FluxConcatMap.java:121)
at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40)
at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44)
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60)
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
at reactor.core.publisher.Mono.subscribe(Mono.java:2757)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:167)
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:61)
at reactor.ipc.netty.channel.ChannelOperations.applyHandler(ChannelOperations.java:380)
at reactor.ipc.netty.http.server.HttpServerOperations.onHandlerStart(HttpServerOperations.java:354)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.util.concurrent.ForkJoinPool$DefaultForkJoinWorkerThreadFactory and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.concurrent.SubmissionPublisher["executor"]->java.util.concurrent.ForkJoinPool["factory"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:312)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:950)
at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:129)
... 65 common frames omitted
Update 1: The complete source codes for Java 9.
#GetMapping
public Flow.Publisher<Post> all() {
SubmissionPublisher publisher = new SubmissionPublisher();
publisher.submit(new Post(1L, "post one", "content of post one"));
publisher.submit(new Post(2L, "post two", "content of post two"));
return publisher;
}
Update 2: In the reference doc of Spring 5.0.0.RELEASE, I can not find the statement there.
Update 3: Updated the Spring 5.0.2(managed by Spring Boot 2.0.0.M7), the codes is running well without any exceptions, but it will block the request when access it. Check my updated sample codes.
Indeed, this is not supported right now.
Please subscribe to the issue SPR-16052 to know when it's available.
What about this
#RestController
public class Controller {
#GetMapping("/one")
Publisher<String> one(){
return JdkFlowAdapter.publisherToFlowPublisher(Flux.just("one", "two"));
}
}
If you read carefully the first line of the stacktrace, you see that the encoder cannot serialize the object of type java.util.concurrent.ForkJoinPool referenced
from the SubmissionPublisher. Indeed, threads (and so thread pools) cannot be serialized.
You can avoid direct reference to the ForkJoinPool with a proxy executor:
Executor proxyExecutor = (Runnable command)-> ForkJoinPool.commonPool().execute(command);
SubmissionPublisher publisher = new SubmissionPublisher(proxyExecutor);
when I use Fresco frame and do method Fresco.initialize(this); it crush on android system 4.2.2. it won't crush on other system.
02-24 14:12:59.298 17984-17984/com.example.deti:push E/dalvikvm: Could not find class 'com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilderSupplier', referenced from method com.facebook.drawee.backends.pipeline.Fresco.initializeDrawee
02-24 14:12:59.306 17984-17984/com.example.deti:push E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: com.facebook.imagepipeline.core.ImagePipelineFactory
at com.facebook.drawee.backends.pipeline.Fresco.initialize(Fresco.java:32)
at com.example.deti.CustomApplication.onCreate(CustomApplication.java:48)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1070)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4701)
at android.app.ActivityThread.access$1300(ActivityThread.java:171)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1453)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5468)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:936)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
at dalvik.system.NativeStart.main(Native Method)
public class CustomApplication extends MultiDexApplication {
public static Context applicationContext;
#Override
public void onCreate() {
super.onCreate();
applicationContext = this;
MultiDex.install(this);
//创建默认的ImageLoader配置参数
//腾讯bugly接入
Fresco.initialize(this);
pay attention the parent class,when I change Application to MultiDexApplication,it runs correctly on system 4.2.2