Search code examples
jakarta-eecdi

CDI alternatives with priority not working as expected? What would be the possible cause?


When I tried to experiment CDI alternatives with priority, it's working the reverse way, The bean with the least priority was chosen instead of the highest priority bean. How alternatives with priority works?

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
    <alternatives>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.RegularGreeting</class>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.FancyGreeting</class>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.PriorityGreeting</class>
    </alternatives>
</beans>

Greeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

    public interface Greeting {

        public String greet(final String greet);

    }

FancyGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION + 1)
public class FancyGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "schöner Tag,  " + greet;
    }        
}

PriorityGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION + 2)
public class PriorityGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "der Vorrang, Hello, " + greet;
    }
}

RegularGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION)
public class RegularGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "hello " + greet;
    }
}

AlternativesPriorityController.java

 package org.bala.java.jee.cdi.alternatives.priority.controller;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

    import org.bala.java.jee.cdi.alternatives.priority.entity.Greeting;

    @ApplicationScoped
    public class AlternativesPriorityController {

        @Inject
        Greeting greet;

        public String getGreet(String string) {
            return greet.greet(string);
        } 
    }

AlternativesPriorityResource.java

package org.bala.java.jee.cdi.alternatives.priority.boundary;

import javax.inject.Inject;
import javax.json.Json;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;

    import javax.ws.rs.core.Response;

    import org.bala.java.jee.cdi.alternatives.priority.controller.AlternativesPriorityController;

    @Path("/alternatives")
    public class AlternativesPriorityResource {

        @Inject
        AlternativesPriorityController controller;

        @Path("/priority")
        @GET
        public Response getGreet() {
            return Response.ok(Json.createObjectBuilder().add("Greet", controller.getGreet("Princess !")).build(), MediaType.APPLICATION_JSON).build();
        }
    }

outputs :

{
  "Greet": "hello Princess !"
}

But the desired output is,

    {
      "Greet": "der Vorrang, Hello, Princess !"
    }

Thanks.

Updated beans.xml as suggested by @BalusC

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all"> 
</beans>

Solution

  • It's because you registered them as well in beans.xml with RegularGreeting ranked highest. XML configuration always overrides annotation configuration. In other words, the @Alternative is completely ignored.

    Just remove the whole <alternatives> section from beans.xml, then @Alternative can do its job together with @Priority.