Java-EE-compatible AbstractExecutorService Implementation (Part 2)

Here is another take on my previous post???this time using a @Singleton EJB with bean-managed concurrency. First, I introduce a valid interface, but one which is essentially identical to Executor, with the added restriction that execution must be as…

Here is another take on my previous post—this time using a @Singleton EJB with bean-managed concurrency.  First, I introduce a valid interface, but one which is essentially identical to Executor, with the added restriction that execution must be asynchronous (while this is a common thing for “regular” Executors to do, it is not strictly speaking required of them).  I do this for the essential bits of @Asynchronous dispatching (once you see that code below you’ll see why).  While you could certainly use this as a business interface, I wouldn’t really expect you to.  Here’s the AsynchronousExecutor interface:

public interface AsynchronousExecutor {
  public void executeAsynchronously(final Runnable runnable);
}
And now the re-done ExecutorServiceBean:

@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Local({Executor.class, ExecutorService.class, AsynchronousExecutor.class})
@Singleton
public class ExecutorServiceBean extends AbstractExecutorService implements ExecutorService, AsynchronousExecutor {

  @Resource
  private SessionContext sessionContext;

  @Override
  public void execute(final Runnable runnable) {
    if (runnable != null) {
      if (this.sessionContext != null) {
        final AsynchronousExecutor self = this.sessionContext.getBusinessObject(AsynchronousExecutor.class);
        assert self != null;
        self.executeAsynchronously(runnable);
      } else {
        runnable.run();
      }
    }
  }

  @Asynchronous
  @Override
  public void executeAsynchronously(final Runnable runnable) {
    if (runnable != null) {
      runnable.run();
    }
  }

  @Override
  public boolean awaitTermination(final long timeout, final TimeUnit unit) {
    return false;
  }

  @Override
  public boolean isTerminated() {
    return false;
  }

  @Override
  public boolean isShutdown() {
    return false;
  }

  @Override
  public void shutdown() {

  }

  @Override
  public List<Runnable> shutdownNow() {
    return Collections.emptyList();
  }

}

I made a couple of changes:
  • First, I took advantage of the fact that
    AbstractExecutorService actually arranges all the work for you such that really all you have to override is the Executor#execute(Runnable) method.  Specifically, I no longer override the AbstractExecutorService#submit(Callable) method.
  • Second, I made sure that the invocation of the execute(Runnable) method is not itself declared to be @Asynchronous, but delegates this call to the executeAsynchronously(Runnable) method, which is declared to be @Asynchronous.  This is because the innards of the AbstractExecutorService class call the execute(Runnable) method directly.  Since the asynchronous behavior of an @Asynchronous-annotated method can only be accomplished if the control flow progresses through the container, this cumbersome construct is necessary.  One big assumption I made here is that access to the SessionContext object is already properly synchronized by the container, so I performed no additional locking here.  I didn’t find anything in the EJB specification to support or contradict this assumption.
  • The bean is now a @Singleton with bean-managed concurrency.  Even though it has bean-managed concurrency, there are no explicit synchronization primitives anywhere, because they are locked up (ha ha) inside the AbstractExecutorService innards, which do whatever they do, in disturbingly precise and awesome Doug Lea fashion.
  • The bean’s set of @Local business interfaces now includes AsynchronousExecutor.class, so that the container dispatch by way of SessionContext#getBusinessObject(Class) can work.  Like I said earlier, you could use this as a business interface, but it probably would be excessively narrow.
Thanks for all the comments and input.

Java-EE-compatible AbstractExecutorService Implementation

I had one of those should-have-seen-it-years-ago moments today. I was reading through the EJB specification and was paying particular to one of my favorite sections, good ol’ section 21.2.2, which has a part in it that goes a little something like…

I had one of those should-have-seen-it-years-ago moments today.

I was reading through the EJB specification and was paying particular to one of my favorite sections, good ol’ section 21.2.2, which has a part in it that goes a little something like this:

An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances, except if it is a Singleton session bean with bean-managed concurrency.

I have read this section probably, what, dozens of times, and have taken away from it that in general a session bean shouldn’t use the synchronized keyword, or various lock classes.  Then usually I move on.

Today I paused for a moment, and I’m glad I did.  What I realized—which is probably obvious to all of you—is that this does not say that a session bean cannot use the synchronized keyword.  It says that it cannot use the synchronized keyword to synchronize its own innards, because this might prevent the container from spreading calls out to bean instances across multiple hosts.

For probably years I’ve been studiously careful to avoid synchronization primitives or libraries that use them inside my various session beans, because I was just blindly following what I thought the specification said.  Turns out I was wrong.

So I turned around and immediately wrote this, which I’ve needed for eons:

@Local({Executor.class, ExecutorService.class})
@Stateless(name = “ExecutorService”)
public class ExecutorServiceBean extends AbstractExecutorService implements ExecutorService {

  @Resource
  private SessionContext sessionContext;

  @Override
  public void execute(final Runnable runnable) {
    if (runnable != null) {
      runnable.run();
    }
  }

  @Override
  public <T> Future<T> submit(final Callable<T> callable) {
    RunnableFuture<T> returnValue = null;
    if (this.sessionContext == null || !this.sessionContext.wasCancelCalled()) {
      returnValue = this.newTaskFor(callable);
      returnValue.run();
    }
    return returnValue;
  }

  @Override
  public boolean awaitTermination(final long timeout, final TimeUnit unit) {
    return false;
  }

  @Override
  public boolean isTerminated() {
    return false;
  }

  @Override
  public boolean isShutdown() {
    return false;
  }

  @Override
  public void shutdown() {

  }

  @Override
  public List<Runnable> shutdownNow() {
    return Collections.emptyList();
  }

}

It’s an AbstractExecutorService that is implemented as a stateless session bean itself via the @Asynchronous annotation.  The use of synchronized is confined to the AbstractExecutorService‘s underlying CompletionService, which is based around a LinkedBlockingQueue.  You can’t shut it down or terminate it, obviously, and less obviously you can’t portably keep track of the tasks in flight (although I’m thinking that either an @ApplicationScoped list of such tasks or a @SessionScoped list of such tasks could be @Injected here to do so) but short of that it should honor the contract.  Throw tomatoes.

Error Handling Done Right, Part 1

So I had this idea that error handling has been done badly for years (maybe forever (cf. awk’s “bailing out at line 1”)). There are a couple camps here.The first camp worships at the church of error codes and says, well, just as with BASIC line nu…

So I had this idea that error handling has been done badly for years (maybe forever (cf. awk’s “bailing out at line 1”)).

There are a couple camps here.

The first camp worships at the church of error codes and says, well, just as with BASIC line numbers, you define some error codes with some gaps in them—100 should be enough—and then you shoehorn every possible error condition into what amounts to a really poor compression scheme.

“I couldn’t find the X because the Y was unavailable even though the Z was responding” becomes, simply, lossily, 404.

This is the way that error handling has been done from the late 1960s till (through?) now. Wanna find out what really happened? Start digging, bearing in mind that a “not found”-type error is what you’re really looking for.

The second camp says rather officiously: well, clearly that’s not enough; we need to augment this poor lossy compression scheme with some other poor lossy compression schemes. That will solve all our problems. And so you get ANSI and X/Open dueling on exactly what a SQLState is. Anyway, this extra cryptic number, which never tells you what standards body coined it, conjoined with the equally inscrutable error code number, paired with the vendor’s own set of error codes, makes everything crystal clear. Right? No?

Look, we can all describe the process that we go through when we get a Java stack trace (I’m a Java guy; the rest of this is about Java error handling). It goes something like this:

  1. The developer gets a stack trace (because, er, someone else’s code died, not his).
  2. The developer says, “WTF?” and then begins combing through the piles of garbage. You scan from the top towards the bottom. The top is generally irrelevant; as you get closer to the bottom you get more interested.
  3. At this point the details of the stack trace are entirely irrelevant. They may very well become relevant later, but for now the developer wants to know: was it a SQLException? Was it a JNDI lookup exception? Was it one of those wrapping the other kind? Are there other things that stand out as the elevator goes lower? Scroll, scroll, scroll.
  4. The developer stumbles across the problem, which may very well not be the root cause, but which I bet you is near the bottom. We’re getting closer to the actual carnage.
  5. The developer may notice some other accreted state hanging off the Throwable chain as he descends; often without realizing it, he files it away (“Blah blah blah…foreign key…oh, hmm; interesting….”).
  6. After this quick skim, which typically takes a second or two, the developer can construct a pseudo-literate, pseudo-native-language sentence about what went wrong. “Ahhhh, OK, the frobnicator blew up because it couldn’t find the data source during user login—huh, that’s funny; the user name has some Unicode characters in it—which happened with that crufty old SSO ‘solution’ we purchased from YoYoDyne a while back; I bet they might have something to say here; Joe told me he thought they didn’t use foreign keys…hmm.”

Let’s look at step six.

Step six has the message that anyone remotely technical is going to need to begin to figure out how to fix the problem.

You’ll note that the message in step six did not come from one of the Throwables in the stack trace directly, nor any of its embedded messages. It came from bits of information scattered throughout the stack.

You’ll also note that step six does not feature an error code, though perhaps an error code of some vendor variety was involved (typically in step five). Nor does it feature a so-called disambiguating error code, or an error code that is intended to disambiguate the disambiguating error code. That’s in part because we all ignore error codes as a matter of course because they’re largely useless. That’s because they’re bad, lossy compression schemes that lose the very information you need. But I digress (sorry!).

You’ll notice that step six makes reference to some state that probably occurred higher up the Throwable chain (the fact that the user id had some Unicode characters in it).

Instead, what the developer did was pattern match—the pattern matched the Throwable chain, and, once a pattern he didn’t even know he was looking for was encountered, constructed the appropriate message for that chain (in his head).

So why don’t error messages work this way? Why do we make humans do this?

Because we’re lazy, that’s why, and also because at the point that we throw a Throwable we have no idea what’s going on in the system as a whole. It’s only when we catch a Throwable that we have the tools available to figure out what happened.

See, the thrower only knows that his little piece of the puzzle has failed. Usually this is because some inscrutable bit of machinery beneath him has failed. So he dutifully does the following:

try {
  frobnicator.frobnicate();
} catch (final FrobnicationException kaboom) {
  throw new BorkificationException("Encountered problem frobnicating", kaboom);
}

Ye gods. No wonder technologists accrue a reputation for being hopelessly out of touch. By the time this thing has passed up through other layers, we get some godawful stack trace like:

com.yourstartup.EnbratzificationException: Error in enbratzifying
    at com.yourstartup.Enbratzifier.enbratzify(Enbratzifier.java:120)
    [and so on]
Caused by: com.yourstartup.BorkificationException: Borkification died
    at com.yourstartup.Borkifier.borkify(Borkifier.java:307)
    [and so on]
Caused by: com.yourstartup.FrobnicationException: Encountered problem frobnicating
    at com.yourstartup.Frobnicator.frobnicate(Frobnicator.java:566)
    [and so on]
Caused by: com.yourstartup.CaturgiationException: caturgiating didn't work
    at com.yourstartup.Caturgiator.caturgiate(Caturgiator.java:1544)
    [and so on]

Quick! What happened? Oh, no! The whole system…it’s f***ed! We’re all going to die!

But, see, you know. You honed this ability a long time ago.

Because if you’re experienced, it will take you less than a quarter of a second to realize that the Enbratzifier couldn’t borkify because the Frobnicator exploded while caturgiating. And that will probably start you immediately thinking about frobnication in the context of enbratzification, but only when the Borkifier is properly configured, and how come the…. Congratulations; you’ve just engaged in some sophisticated pattern matching, and you’ve come up with a useful error message.

Computers are really good at pattern matching. So how come we don’t use pattern matching for error handling?

Part of the reason is architectural. We’ve all been trained that a layer is supposed to be ignorant of the layers above it, and should know only about the layer beneath it.

But when you surfed through the stack trace above, you didn’t pay any heed to these architectural principles—nor should you have. When errors are involved, architecture goes out the window. That’s because by the time the error has been encountered, the architecture has failed: something died, so you need to go pick up the bodies, and you’ll be damned if some ivory tower notion of isolation is going to stand in your way. Good for you.

So you busted through the layers like a hot knife through butter. You dug down the stack, glossed over and yet somehow retained bits of state (messages) involved in lower layers, and by mining this sludge you came to your conclusion.

You need an error handling library that does the same thing. If a big hairy Throwable chain matches a sophisticated pattern, then the library should let you construct a message based off the information encoded throughout the chain, and in its very structure.

Stay tuned for part 2, in which our hero descends into non-deterministic finite automata theory to bring this to fruition. It’s also where our hero takes a lot of Advil.

JAXB and interfaces

My readership (hi, both of you) may notice that my previous article on JAXB interfaces has been taken down. I did it on purpose, so there.I had posted it, and I think it was substantially correct. Then I started messing with it. After a few experi…

My readership (hi, both of you) may notice that my previous article on JAXB interfaces has been taken down.?? I did it on purpose, so there.

I had posted it, and I think it was substantially correct.?? Then I started messing with it.

After a few experiments, I managed to leave behind an annotated package-info.java file that led me to think I was seeing results I actually wasn't seeing.?? That led me to question my own post and to edit and update it twice.?? By the time I realized my mistake, the damage was done, so I took the post down to make sure I didn't further muddy the already polluted JAXB waters out there.

Thanks to Blaise Doughan for a pointer to his own document on working with interfaces and JAXB.

One area I'm still interested in is late binding of implementation classes to interfaces.?? In my project, I have a one-to-one correspondence of implementation to interface, but it is not known which implementation will be used until .ear file packaging time.?? The interface packages don't have compile-time visibility into the implementation packages (if yours do, you're Doing It Wrong), so specifying XmlAdapters with good type information is impossible.?? I can use XmlAdapter<Object, Object> to break the compile-time annotation dependency as recommended in the inscrutable Unofficial JAXB Guide, but that leads to some very funky XML output featuring lots of namespace declarations and things like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
?????? <age>61</age>
?????? <habit xsi:type="habitImplementation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
?????????????? <name xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">Staying up late coding</name>
?????? </habit>
?????? <name xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Fred</name>
</person>

(How come the <name> element needs its type specified?)

I'd like to use the excellent Swiss Army knife approach of @XmlJavaTypeAdapters applied to a package-info.java file, but I don't actually want to specify this until the moment when I'm packing up my .ear file.?? At that point I will know (or can know, anyhow) what single implementation of a hypothetical Person interface, for example, will be used.

I know I'm ignoring lots of complexities and whatnot and surely there are valid reasons why the following is a bad idea, but it all sure would be simpler if it were possible to have the type attribute of @XmlElement take a String, not a Class, and get resolved at runtime.?? After all, how many times does an interface actually have a compile time dependency on its implementation class??? Zero, in almost every case I can think of.

I am currently musing over a nasty but intriguing stew of a Maven plugin, Javassist and programmatically generated package-info.class files to basically produce a big list of XmlAdapter specifications.?? The pro is this should get me exactly what I want.?? The con is this shouldn't be this difficult.

Zeroing out times in java.util.Date the right way

File this one under The Mob Is Coming For java.util.Date Author Alan Liu With Flaming Torches And Pitchforks (one in a long series).Folks who have worked with Java’s java.util.Date and java.util.Calendar classes know that when you create a new Dat…

File this one under The Mob Is Coming For java.util.Date Author Alan Liu With Flaming Torches And Pitchforks (one in a long series).

Folks who have worked with Java’s java.util.Date and java.util.Calendar classes know that when you create a new Date object without any arguments it is initialized with a long representing the number of milliseconds since the epoch.

Sometimes you need a Date that just has its date fields initialized. Here is the only way to do it properly, ensuring that all date fields are set to their defaults, and all time fields are set to their minimums. Anything else runs the risk of missing a time or date field or two, or uses a deprecated constructor, or is not performant, or all three.

final Calendar calendarNow = Calendar.getInstance();
assert calendarNow != null;
calendarNow.set(Calendar.HOUR_OF_DAY, calendar.getMinimum(Calendar.HOUR_OF_DAY));
calendarNow.set(Calendar.HOUR, calendar.getMinimum(Calendar.HOUR)); // for maximum correctness and safety you need to set both (!)
calendarNow.set(Calendar.MINUTE, calendar.getMinimum(Calendar.MINUTE));
calendarNow.set(Calendar.SECOND, calendar.getMinimum(Calendar.SECOND));
calendarNow.set(Calendar.MILLISECOND, calendar.getMinimum(Calendar.MILLISECOND));
calendarNow.set(Calendar.AM_PM, calendar.getMinimum(Calendar.AM_PM)); // this makes it "really correct" for future modifications
final Date now = calendarNow.getTime();
assert now != null;

Getting Jenkins Running On A Mac

I wanted to blog about how to get Jenkins running on a Mac using its installer.Jenkins is a great product, but its frenetic and crazed (but cheerful and enthusiastic) development process often shows through. Case in point: the default Mac installe…

I wanted to blog about how to get Jenkins running on a Mac using its installer.

Jenkins is a great product, but its frenetic and crazed (but cheerful and enthusiastic) development process often shows through.

Case in point: the default Mac installer, which you can download from the jenkins-ci.org website, sets up Jenkins to run as a Mac LaunchDaemon running as user daemon.

Now, there's nothing inherently wrong with this–indeed, it can be quite nice.?? You'll only have one instance of Jenkins running, and no user needs to be logged on for it to do its thing, and if Jenkins ever got hacked you're running as a low-privilege user rather than as some kind of full-fledged user with the ability to ruin your day.

However, this caused some weird problems, nullifying the entire intent of a one-click installer.?? These problems manifest themselves the moment you try to run a Maven build, which suggests to me that this (simple) smoke test is simply not run before new versions of the installer are released.?? Oh well, time to roll up our sleeves and turn the one-click installation process into an exercise in Mac system administration.?? 🙂

What's wrong with daemon?

The first thing to know about user daemon is that his home directory is /var/root.?? That should start to give you a funny feeling.

The reason that should give you a funny feeling is that Maven looks for its settings.xml file in $HOME/.m2.?? Which of course does not exist in /var/root.

So when Jenkins launches, it appears to come up fine.?? But if you try to run a Maven build, you'll get a lovely stack trace about how the file /var/root/.m2 couldn't be created.

When I first encountered this error, I just wanted to get the stupid thing working, so I did:


sudo mkdir -p /var/root/.m2

…and:


sudo chmod a+rwx /var/root/.m2

So this gets Jenkins-running-as-daemon past this problem, but now it wants to create temporary files in /Users/Shared/Jenkins/Home, which it doesn't own, and can't write to.

At any rate, I now realized that I didn't want this thing running as user daemon anyway, because I didn't want him doing anything to /var/root.?? And even if I could somehow tell him to use a different user directory so that $HOME/.m2/settings.xml would be resolved somewhere else, it was clear that I was going to have to edit .plist files.?? So, so much for the installer.?? And as long as the installer wasn't going to work, I decided that I wanted to make Jenkins run as a different kind of daemon user anyway.

This turned out (for this rookie Mac system administrator) to be quite difficult.

The steps involved are:

  1. Create a daemon user (I called mine _jenkins)
  2. Create a daemon group (I called mine???surprise!???_jenkins)
  3. Put the daemon user in the newly-created daemon group
  4. Create the home directory for the new daemon user (/Users/_jenkins in my case)
  5. chown the /Users/Shared/Jenkins directory so that its hierarchy is owned by your new user.
  6. edit /Library/LaunchDaemons/org.jenkins-ci.plist so that it reflects all this information.

Creating the user is a task that should not be accomplished through the usual Mac GUI methods.?? You need to use dscl instead.?? This is because you want to create a daemon user.?? I snooped around for a bit and came up with this lovely tutorial: http://www.minecraftwiki.net/wiki/Tutorials/Create_a_Mac_OS_X_startup_daemon#The_hard_.28and_correct.29_way.?? It walked me through steps 1-4 above.

Then I did:


sudo chown -R _jenkins:_jenkins /Users/Shared/Jenkins

Finally, my /Library/LaunchDaemons/org.jenkins-ci.plist looks like this:


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
?????? <dict>
?????????????? <key>EnvironmentVariables</key>
?????????????? <dict>
?????????????????????????????? <key>JENKINS_HOME</key>
?????????????????????????????? <string>/Users/Shared/Jenkins/Home</string>
?????????????????????????????? <key>_JAVA_OPTIONS</key>
?????????????????????????????? <string>-Dfile.encoding=UTF-8</string>

?????????????? </dict>
?????????????? <key>GroupName</key>
?????????????? <string>_jenkins</string>
?????????????? <key>KeepAlive</key>
?????????????? <true/>
?????????????? <key>Label</key>
?????????????? <string>org.jenkins-ci</string>
?????????????? <key>ProgramArguments</key>
?????????????? <array>
?????????????????????????????? <string>/bin/bash</string>
?????????????????????????????? <string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
?????????????? </array>
?????????????? <key>RunAtLoad</key>
?????????????? <true/>
?????????????? <key>UserName</key>
?????????????? <string>_jenkins</string>
?????? </dict>
</plist>

I added the _JAVA_OPTIONS environment variable to force UTF-8 encoding.?? This is because no matter what kind of encoding you might specify in your Java code, Java-on-the-Mac's character encoding for what gets put out to the terminal is MacRoman by default (?!).?? You have to get the file.encoding property passed into the JVM early enough so that it is picked up by the rest of the JVM internals, and the only way to do that is to use the special _JAVA_OPTIONS environment variable picked up by all the Java tools in $JAVA_HOME/bin.?? The only unfortunate side effect of all this is that you get a warning printed to the screen on every JVM startup that says, effectively and incomprehensibly, I am using the environment variable you told me to.

Once you've done all this, you can simply stop the launch daemon and it will automatically restart with the new values:


sudo launchctl stop org.jenkins-ci

I hope that helps other Jenkins Mac users out.

jpa-maven-plugin Released

I’m pleased to announce to my enormous reading audience (both of you) the jpa-maven-plugin project. Please peruse the documentation, the Javadocs and then finally try using it and let me know what you think.

I'm pleased to announce to my enormous reading audience (both of you) the jpa-maven-plugin project.

Please peruse the documentation, the Javadocs and then finally try using it and let me know what you think.