Make Sure Log Messages Show Up (Programmatically)

Here’s a quick snippet that shows how, using java.util.logging, to ensure that log messages actually show up on your console without the hassle of editing or specifying a logging.properties file somewhere.  This is useful particularly for unit tests featuring the javax.ejb.embeddable.EJBContainer class.


final Logger topLogger = Logger.getLogger("");
assert topLogger != null;
Handler consoleHandler = null;
final Handler[] handlers = topLogger.getHandlers();
if (handlers != null && handlers.length > 0) {
for (final Handler handler : topLogger.getHandlers()) {
if (handler instanceof ConsoleHandler) {
consoleHandler = handler;
break;
}
}
}
if (consoleHandler == null) {
consoleHandler = new ConsoleHandler();
topLogger.addHandler(consoleHandler);
}
consoleHandler.setLevel(Level.FINEST);

How to Override an @EJB Reference

I found this very simple in the end, but tracking it down and getting the concepts right was surprisingly difficult.  What follows is just my rephrasing of all the bits—it’s nothing revolutionary.

When you use the @EJB annotation in any way, shape or form, you declare an EJB reference.  You say, “I am going to use an EJB, and directly or indirectly I’m going to look for it under a particular name in my java:comp/env JNDI namespace.”  The actual JNDI lookup may be hidden, but it is important to realize that at least conceptually it is always there.

If you use the name attribute of the @EJB annotation, then you are also saying: “In addition to declaring an EJB reference, I’m also (for whatever reason) going to give this reference a name.”  You can name it anything you want.  The value you supply to the name attribute of the @EJB annotation will be relative (in JNDI) to java:comp/env. This name does not intrinsically identify a bean. It identifies a “slot” in JNDI where a bean is expected to reside such that your bean can find it. Making a bean arrive in this slot is the container’s responsibility, or the Application Assembler’s responsibility.

If you do not use the name attribute of the @EJB annotation, then it is exactly as though you supplied classname/fieldname as a value for the name attribute (if you annotated a field, the most common case). That is, the following two snippets are exactly equal:


package foo;
@Stateless
public class CaturgiatorBean {
@EJB
private Frobnicator frobnicator;
}

The following snippet spells out what was only implied above:


package foo;
@Stateless
public class CaturgiatorBean {
@EJB(name = "foo.CaturgiatorBean/frobnicator")
private Frobnicator frobnicator;
}

If you put an @EJB annotation on a class, you are saying: “In this class, somewhere, someone will look up an EJB under a particular name in JNDI.  Please be prepared for this to happen so they don’t get a NullPointerException or something worse.” This usage of @EJB doesn’t do anything besides simply declare that the bean will be looking for something in a given slot in JNDI.

The @EJB annotation is equal to either the <ejb-local-ref> or <ejb-ref> deployment descriptor element. If you used it on a field whose type is a local business interface of another EJB somewhere, then it’s as though you specified an <ejb-local-ref> in the deployment descriptor.

The minimal way to override a situation like either of the examples above using an ejb-jar.xml file is to include the following snippet:


<?xml version="1.0" ?>
<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>ReferencingBeanName</ejb-name>
<ejb-local-ref>
<ejb-ref-name>referencing.bean.pkg.ReferencingBean/fieldStoringReferencedBeanProxy</ejb-ref-name>
<ejb-link>ReferencedBeanName</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>

view raw

ejb-jar.xml

hosted with ❤ by GitHub

Making EclipseLink Logging Play Nice With GlassFish 3.1.2.2

To get logging working properly with EclipseLink 2.3.2 and GlassFish 3.1.2.2, you want to configure the actual logging values in GlassFish’s logging.properties file, not in your META-INF/persistence.xml file.  You have to set two levels (a bit mysterious, as one is a child of the other; setting values on the parent logger should cause them to flow downhill, but for some reason they do not).

Then, to be able to see SQL parameters in the output, you have to set a property in your META-INF/persistence.xml file.

Assuming you have a domain called domain1:

  • Edit $GLASSFISH_HOME/glassfish/domains/domain1/config/logging.properties and add the following lines:
    1. org.eclipse.persistence.level = FINE
    2. org.eclipse.persistence.sql.level = FINE
      • The first allows you to see SQL statements.  The second must be set in order for SQL parameters to be seen, but it is not sufficient on its own.
  • In your META-INF/persistence.xml, add the following element as a child of the <properties> element:
    <property name="eclipselink.logging.parameters" value="true"/>