Vi har i vår applikation jag jobbar med en JPA-lyssnare som vi vill skall sköta spårbarheten, när en entitet blir insertad eller uppdaterad i databasen skall det slängas med en tidsstämpel och användarnamn på användaren som ändrade/skapade entiteten. Normalt är man ju i en sessionsböna och kan komma åt användaren med getCallerPrincipal() på en injicerad EjbContext men eftersom vi är i en pojo så kan vi inte komma åt vår principal den vägen.

Lyssnaren ser ut såhär:

public class Spårbarhetslyssnaren {
  @PreUpdate
  public void föreUpdate(SpårBarEntitet entitet) {
      Subject caller = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
      Set principals = caller.getPrincipals(SpecialPrincipal.class);
      SpecialPrincipal principal = (SpecialPrincipal) principals.iterator().next();
      entitet.sättVemSomGjordet(principal.getVemSomGjört());
  }
}

Men när jag körde så fick jag NullPointerException eftersom getContext inte behagade returnera någonting. Efter mycket letande hittade jag en diskussion på en JBoss-mailinglista där det visade sig att man måste specificera säkerhetsdomän även för modulen som innehåller entiteterna/lyssnaren. Vi hade tidigare bara specat detta för vårt affärslogiklager eftersom det bara är det som innehåller remote-ejb:er.

Så, glöm inte att sätta upp security-domain i en jboss.xml för den modul som innehåller entiteter/fasadbönor/lyssnare om du inte har dem i samma modul som dina remotebönor.

Nu när jag läser det här lite senare så känns det lite otydligt. Med modul menar jag alltså jar-fil som är en del av enterprise applikationens .ear-paket. Så säg att man har ett par webapplikationer, en jar-fil med ejb:er och en med JPA-entiteter så måste man i alla dessa paket ha en jboss.xml som specar security-domain.