micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.07k stars 1.07k forks source link

@Introspected annotation doesn't work when used in a shared module #2295

Closed aruld closed 4 years ago

aruld commented 4 years ago

Thanks for reporting an issue for Micronaut, please review the task list below before submitting the issue. Your issue report will be closed if the issue is incomplete and the below tasks not completed.

NOTE: If you are unsure about something and the issue is more of a question a better place to ask questions is on Stack Overflow (http://stackoverflow.com/tags/micronaut) or Gitter (https://gitter.im/micronautfw/). DO NOT use the issue tracker to ask questions.

Task List

Steps to Reproduce

  1. Introspected annotation on the DirectionDTO bean resides in its own module (maps-common) which is shared by service and gateway modules.

The repository definition in the service module looks like this:

public interface DirectionRepository extends CrudRepository<Direction, Long> {

    List<DirectionDTO> findByStartAndEndAndProviderOrderByPositionAsc(Place start, Place end, MapProvider provider);

    // this works, not the DTO variant above
    //List<Direction> findByStartAndEndAndProviderOrderByPositionAsc(Place start, Place end, MapProvider provider);
}

It should not be required to annotate Direction JPA entity with @Introspected.

  1. Steps to reproduce: git clone https://github.com/aruld/maps-app.git git checkout micronaut-data-support

Run consul:

docker run -p 8500:8500 consul:1.4.4

Run the service from maps-service dir: ./gradlew run

Run the gateway from maps-gateway dir: ./gradlew run

Invoke the API using curl: curl "http://localhost:8080/api/maps/fastest?src=apple&dest=google"

Expected Behaviour

{"directions":[{"position":0,"text":"Turn right onto N Shoreline Blvd","distanceInMiles":0.3,"timeInMinutes":1},{"position":1,"text":"Take a slight right turn to merge onto CA-85 South","distanceInMiles":0.6,"timeInMinutes":1},{"position":2,"text":"Keep left to merge onto CA-85 South","distanceInMiles":0.2,"timeInMinutes":1},{"position":3,"text":"Take the exit to merge onto I-280 toward San Jose","distanceInMiles":5.4,"timeInMinutes":6},{"position":4,"text":"Take exit 11 onto De Anza Boulevard","distanceInMiles":1.5,"timeInMinutes":1},{"position":5,"text":"Turn right onto N De Anza Blvd toward Cupertino, Saratoga","distanceInMiles":0.2,"timeInMinutes":1},{"position":6,"text":"Turn left onto Mariani Ave","distanceInMiles":0.3,"timeInMinutes":1}],"timeInMinutes":12}

Actual Behaviour

It fails with an introspection error on the client side:

{"message":"Internal Server Error: Internal Server Error: Internal Server Error: Error instantiating type [maps.common.DirectionDTO] from introspection: No bean introspection available for type [class maps.common.DirectionDTO]. Ensure the class is annotated with io.micronaut.core.annotation.Introspected"}

Service errors with this exception trace:

14:51:17.201 [nioEventLoopGroup-1-12] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error instantiating type [maps.common.DirectionDTO] from introspection: No bean introspection available for type [class maps.common.DirectionDTO]. Ensure the class is annotated with io.micronaut.core.annotation.Introspected
io.micronaut.data.exceptions.DataAccessException: Error instantiating type [maps.common.DirectionDTO] from introspection: No bean introspection available for type [class maps.common.DirectionDTO]. Ensure the class is annotated with io.micronaut.core.annotation.Introspected
        at io.micronaut.data.runtime.mapper.BeanIntrospectionMapper.map(BeanIntrospectionMapper.java:97)
        at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations$2.tryAdvance(DefaultJdbcRepositoryOperations.java:334)
        at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.lambda$findAll$6(DefaultJdbcRepositoryOperations.java:396)
        at io.micronaut.transaction.support.AbstractSynchronousTransactionManager.executeRead(AbstractSynchronousTransactionManager.java:157)
        at io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findAll(DefaultJdbcRepositoryOperations.java:394)
        at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:52)
        at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:36)
        at io.micronaut.data.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:79)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:69)
        at maps.service.DirectionRepository$Intercepted.findByStartAndEndAndProviderOrderByPositionAsc(Unknown Source)
        at maps.service.DirectionService.getDirections(DirectionService.java:29)
        at maps.service.DirectionController.getDirections(DirectionController.java:24)
        at maps.service.$DirectionControllerDefinition$Intercepted.$$access0(Unknown Source)
        at maps.service.$DirectionControllerDefinition$Intercepted$$proxy0.invokeInternal(Unknown Source)
        at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:145)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:60)
        at io.micronaut.validation.ValidatingInterceptor.intercept(ValidatingInterceptor.java:122)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:69)
        at maps.service.$DirectionControllerDefinition$Intercepted.getDirections(Unknown Source)
        at maps.service.$$DirectionControllerDefinition$InterceptedDefinition$$exec1.invokeInternal(Unknown Source)
        at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:145)
        at io.micronaut.context.DefaultBeanContext$BeanExecutionHandle.invoke(DefaultBeanContext.java:2844)
        at io.micronaut.web.router.AbstractRouteMatch.execute(AbstractRouteMatch.java:294)
        at io.micronaut.web.router.RouteMatch.execute(RouteMatch.java:122)
        at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildResultEmitter$15(RoutingInBoundHandler.java:1371)
        at io.reactivex.internal.operators.flowable.FlowableDefer.subscribeActual(FlowableDefer.java:35)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableMap.subscribeActual(FlowableMap.java:37)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14868)
        at io.micronaut.http.context.ServerRequestTracingPublisher.lambda$subscribe$0(ServerRequestTracingPublisher.java:52)
        at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
        at io.micronaut.http.context.ServerRequestTracingPublisher.subscribe(ServerRequestTracingPublisher.java:52)
        at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
        at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
        at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:253)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:510)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:518)
        at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

Environment Information

Example Application

jameskleeh commented 4 years ago

Your dependencies in common are incorrect:

compile "io.micronaut:micronaut-core:1.2.5"

should be

    compile "io.micronaut:micronaut-inject:1.2.5"
    annotationProcessor "io.micronaut:micronaut-inject-java:1.2.5"
aruld commented 4 years ago

Thank you @jameskleeh for helping with this.