payara / Payara

Payara Server is an open source middleware platform that supports reliable and secure deployments of Java EE (Jakarta EE) and MicroProfile applications in any environment: on premise, in the cloud or hybrid.
http://www.payara.fish
Other
880 stars 301 forks source link

@Resource annotation in EJB or MDB does not correctely inject env-entry values from ejb-jar.xml /FISH-460 #4741

Closed gottschd closed 2 years ago

gottschd commented 4 years ago

Description

Using a @Resource annotation on a member in an EJB or MDB will not always lead to a correctly initialized value. Sometimes it is null. The value comes from the corresponding "ejb-jar.xml".

Expected Outcome

The member with the @Resource annotation is always initialized correctly and stays stable., i.e. does not change the value from null to not-null in an undeterministic way in case the EJb or MDB is called multiple times.

Current Outcome

The member inside an EJB/MDB annotated with @Resource switches its value between null and not-null in an undeterministic non-stable way.

Steps to reproduce (Only for bug reports)

Sample maven project available here. Deploy the resulting simple-mdb-env-ear.ear from the maven project in payara and watch the server.log file.

Long story short:

  1. Create an MDB

    @JMSDestinationDefinition(name = "java:global/queue/simpleQ", interfaceName = "javax.jms.Queue", destinationName = "simpleQ")
    @MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:global/queue/simpleQ"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
    public class MessageConsumerMdb implements MessageListener {
    @Resource(name = "MyFancyEnvVar")
    private String envVar;
    
    public MessageConsumerMdb() {
        // default ctr
    }
    
    @Override
    public void onMessage(Message message) {
        try {
            System.out.println("Message received by '" + envVar + "' (expected: 'foo'): " + message.getBody(String.class));
        } catch (JMSException ex) {
            ex.printStackTrace();
        }
    }
    }
  2. Create an EJB

    @Stateless
    @LocalBean
    public class MessageProducerEjb {
    @Resource(name = "MyFancyEnvVar")
    private String envVar;
    
    @Inject
    JMSContext ctx;
    
    @Resource(lookup = "java:global/queue/simpleQ")
    Queue queue;
    
    public void sendMessage(String msg) {
        ctx.createProducer().send(queue, msg);
    }
    
    @Schedule(dayOfMonth = "*", dayOfWeek = "*", hour = "*", minute = "*", second = "*/5", persistent = false)
    public void myTimer() {
        sendMessage("From '" + envVar + "' (expected: 'bar') with love. " + new Date().toString());
    }
    }
  3. Package to EAR with the following ejb-jar.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
    version="3.1">
    <enterprise-beans>
        <session>
            <ejb-name>myFancyMessageProducerEjb</ejb-name>
            <ejb-class>org.acme.MessageProducerEjb</ejb-class>
            <session-type>Stateless</session-type>
            <env-entry>
                <env-entry-name>MyFancyEnvVar</env-entry-name>
                <env-entry-type>java.lang.String</env-entry-type>
                <env-entry-value>bar</env-entry-value>
            </env-entry>
        </session>
        <message-driven>
            <ejb-name>myFancyMessageConsumerMdb</ejb-name>
            <ejb-class>org.acme.MessageConsumerMdb</ejb-class>
            <messaging-type>javax.jms.MessageListener</messaging-type>
            <env-entry>
                <env-entry-name>MyFancyEnvVar</env-entry-name>
                <env-entry-type>java.lang.String</env-entry-type>
                <env-entry-value>foo</env-entry-value>
            </env-entry>
        </message-driven>
    </enterprise-beans>
    </ejb-jar>
  4. Deploy the resulting EAR file in payara and watch the server.log.
  5. Log entries similar to the following lines will occur showing that the value injection does not work correct and stable.
    Message received by 'foo' (expected: 'foo'): From 'bar' (expected: 'bar') with love. Tue Jun 23 15:35:50 CEST 2020]]
    Message received by 'null' (expected: 'foo'): From 'bar' (expected: 'bar') with love. Tue Jun 23 15:35:55 CEST 2020]]
    Message received by 'foo' (expected: 'foo'): From 'null' (expected: 'bar') with love. Tue Jun 23 15:35:55 CEST 2020]]
    Message received by 'null' (expected: 'foo'): From 'bar' (expected: 'bar') with love. Tue Jun 23 15:36:00 CEST 2020]]
    Message received by 'foo' (expected: 'foo'): From 'null' (expected: 'bar') with love. Tue Jun 23 15:36:00 CEST 2020]]
    Message received by 'null' (expected: 'foo'): From 'null' (expected: 'bar') with love. Tue Jun 23 15:36:05 CEST 2020]]
    Message received by 'foo' (expected: 'foo'): From 'bar' (expected: 'bar') with love. Tue Jun 23 15:36:05 CEST 2020]]

Environment

gottschd commented 4 years ago

Hi all, it seems to me as an important issue, no? Do I miss something? Are more information necessary? Is there anybody who can also reproduce this? Thanks for feedback.

rdebusscher commented 4 years ago

Hi,

Sorry for the late reply but I can also reproduce it with 5.201 and 5.2020.4. I have created the internal issue /FISH-460 so that the engineering team can investigate this issue further.

Thank you for the reproducer and for reporting this issue.

Best Regards Rudy

rdebusscher commented 2 years ago

This was rejected by dev team some time ago (sorry for the late reply)

The env entry is only defined for the EJBs created via the ejb-jar.xml file (the “fancy” ones), those nulls are coming from the Producer/Consumer that were created by annotations and thus don’t have a env variable definition in the ejb-jar.xml file since they’re bean specific.

Both the annotations and end xml definition creates a set of beans and only the 'XML ones' are configured with env-entries.