Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arc - Inherited Observer methods clash with type variables #25364

Closed
JHahnHRO opened this issue May 4, 2022 · 4 comments · Fixed by #25371
Closed

Arc - Inherited Observer methods clash with type variables #25364

JHahnHRO opened this issue May 4, 2022 · 4 comments · Fixed by #25371
Assignees
Labels
area/arc Issue related to ARC (dependency injection) env/windows Impacts Windows machines kind/bug Something isn't working
Milestone

Comments

@JHahnHRO
Copy link

JHahnHRO commented May 4, 2022

Describe the bug

If an observer method is defined in a superclass of two bean classes and observes a type variable, then the the concrete type of this type variable in the context of the implementing classes is seemingly not taken into account. It seems that only the bounds at the declaration are taken into account.

Expected behavior

The test shown below should succeed when executed with Arc

Actual behavior

Annotated with @EnableAutoWeld the test succeeds. Annotated with @QuarkusTest the test fails with a ClassCastException:

AService#onEvent:class com.example.MyAEvent

java.lang.ClassCastException: class com.example.MyAEvent cannot be cast to class com.example.MyBEvent (com.example.MyAEvent and com.example.MyBEvent are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @4e38d975)

	at com.example.MyBService.doSomething(MyBService.java:5)
	at com.example.AbstractService.onEvent(AbstractService.java:15)
	at com.example.AbstractService_Observer_onEvent_323a4600e644fd71f7085886ea60198dd4e67c76.notify(Unknown Source)
	at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:323)
	at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:301)
	at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:73)
	at com.example.EventSource.sendA(EventSource.java:17)
	at com.example.TestObserverInheritance.testObservers(TestObserverInheritance.java:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:1008)
// rest omitted

suggesting that the event was delivered to the inherited observer method in MyBService. The same happens for async observer methods which I have omitted for brevity.

Admittedly, it is not entirely clear (to me) from the CDI Spec that Weld's behaviour is correct and Arc's is incorrect. The Spec DOES say that an observer method must be non-abstract, so the difference in behaviour for a similar test in which the observer method itself is abstract is not that surprising; it's simply something Weld allows and Arc doesn't. But the spec does not forbid calling abstract methods from a non-abstract observer method.

At the very least, Weld's behaviour is the more intuitive (to me) of the two.

How to Reproduce?

Consider this application

class MyEvent {}
class MyAEvent extends MyEvent {}
class MyBEvent extends MyEvent {}

abstract class AbstractService<E extends MyEvent> {
    int count;

    public int getCount() {
        return count;
    }

    void onEvent(@Observes E myEvent) {
        count++;
        doSomething(myEvent);
    }

    abstract void doSomething(E myEvent);
}


@ApplicationScoped
class MyAService extends AbstractService<MyAEvent>{

    @Override
    protected void doSomething(MyAEvent myEvent) {
        System.out.println("AService#onEvent:"+myEvent.getClass());
    }
}

@ApplicationScoped
class MyBService extends AbstractService<MyBEvent>{
// analogously defined as MyAService
}

@Unremovable
@Dependent
public class EventSource {
    @Inject
    Event<MyEvent> event;

    void sendA(){
        event.fire(new MyAEvent());
    }
}

and the following test:

public abstract class TestObserverInheritance {

    @Inject
    MyAService myAService;

    @Inject
    MyBService myBService;

    @Inject
    EventSource eventSource;

    @Test
    void testObservers() {
        eventSource.sendA();

        assertThat(myAService.getCount()).isEqualTo(1);
        assertThat(myBService.getCount()).isEqualTo(0);
    }
}

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.8.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537) Maven home: C:\Users<me>.m2\wrapper\dists\apache-maven-3.8.4-bin\52ccbt68d252mdldqsfsn03jlf\apache-maven-3.8.4 Java version: 11, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-11 Default locale: de_DE, platform encoding: UTF-8 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Additional information

No response

@JHahnHRO JHahnHRO added the kind/bug Something isn't working label May 4, 2022
@quarkus-bot quarkus-bot bot added area/arc Issue related to ARC (dependency injection) env/windows Impacts Windows machines labels May 4, 2022
@quarkus-bot
Copy link

quarkus-bot bot commented May 4, 2022

/cc @manovotn, @mkouba

@mkouba mkouba self-assigned this May 4, 2022
mkouba added a commit to mkouba/quarkus that referenced this issue May 4, 2022
mkouba added a commit to mkouba/quarkus that referenced this issue May 4, 2022
mkouba added a commit to mkouba/quarkus that referenced this issue May 4, 2022
@quarkus-bot quarkus-bot bot added this to the 2.10 - main milestone May 5, 2022
@gsmet gsmet modified the milestones: 2.10 - main, 2.8.3.Final May 5, 2022
gsmet pushed a commit to gsmet/quarkus that referenced this issue May 5, 2022
gsmet pushed a commit to gsmet/quarkus that referenced this issue May 5, 2022
gsmet pushed a commit to gsmet/quarkus that referenced this issue May 12, 2022
@JHahnHRO
Copy link
Author

The fix did not make it into 2.9.0.Final it seems. Should I open a new issue for that?

@mkouba
Copy link
Contributor

mkouba commented May 16, 2022

The fix did not make it into 2.9.0.Final it seems. Should I open a new issue for that?

@gsmet is it ^ possible?

@JHahnHRO
Copy link
Author

2.9.1.Final does contain the fix again. So all is well, I guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/arc Issue related to ARC (dependency injection) env/windows Impacts Windows machines kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants