“Hey Stan, can I use mockingbird?” Andrew asked, leaning into Stan’s cube. He had to do some rigorous performance testing for a customer-reported issue.

Stan gave a start, ripped out his earbuds, and glanced back nervously. “Use sesame.”

Ah, sesame. Old Faithful, everyone’s go-to server for testing. Unfortunately… “It’s way too slow for what I need to do,” Andrew said. “I don’t need everyone hounding me for making it lag even worse.”

“No one’ll complain.” Stan’s hands shook as he replaced his earbuds. “Just trust me, dude- stay away from mockingbird.” His voice dropped to a whisper. “It’s cursed.”

“What?”

“genCore doesn’t run on mockingbird. Anyone who’s tried to figure out why… well, do you ever see anyone working on mockingbird? Huh?”

“Dude. genCore’s the easiest thing in the world to install and get running,” Andrew said. They were privileged to support one of the rare Java programs that actually delivered on the promise of effortless portability. “I’ll get it working.”

Stan hunched protectively over his keyboard. “Don’t come crying to me when you waste days, weeks, on that thing, and the customer asks for your head.”

“How much you wanna bet I’ll fix it?” Andrew challenged.

“If… if it means I don’t have to use sesame for everything?” Temptation allowed Stan to consider the impossible. “That’s worth a beer,” he whispered.

“Two,” Andrew countered.

“You’re on!”

Full of optimism, Andrew dropped into the lonely cube where the test servers loomed like monoliths. He swiped a layer of dust off the keyboard hooked into mockingbird, and tore away the sign some joker had taped to the monitor: BEWARE, ALL YE WHO ENTER HERE. After logging in, he tried to run genCore, but it exploded with UnknownMethodExceptions.

The stack trace within the program’s log file indicated an issue when loading the JDBC layer. Well, that’s easy, he thought. Probably an old or corrupt version of the JDBC jar.

Andrew copied said jar from sesame to mockingbird, then tried starting genCore on mockingbird again. Same error. He tried uninstalling and reinstalling the program. Same error. Copied over sesame’s jar one more time, and… same error.

The AC vent overhead cut on, sending a chill down Andrew’s spine. genCore was so stable that he never had to troubleshoot beyond the basic “Do you have CLASSPATH properly defined, and are all these jars in place?” Was he just forgetting something idiotic, or was he going crazy? He had to get someone else to look at this. Andrew fled the cube and returned to his own to IM Christine, one of the genCore engineers. Is there some other jar I’m missing or something?

Christine replied: No, that’s it for JDBC. Hang on…

Andrew waited. And waited.

“Hey!”

Andrew yelped and whirled around. Christine stood behind him, grinning. “Time for decaf, I think.”

“Yeah, decaf.” Andrew rubbed at the back of his neck.

“This makes no sense,” Christine said.

“Yeah, I know- crazy, right? Come on.”

Andrew led Christine to the server cube, where they both pulled chairs in front of mockingbird. “Let’s just make 100% sure the jars are the same across both servers,” Christine said.

“I already checked timestamps and file sizes,” Andrew said.

Christine ran through more tricks he wasn’t as familiar with, while a bad storm picked up outside their office walls. Thunder roared at the chance to destroy those within. “jinfo doesn’t report anything unusual. SHA–1 digests are the same. How about javap, checking for the class that’s blowing up?” She ran the command on both servers.

[email protected]:lib$ javap -classpath genCorejdbc.jar com.somepackage.jdbc.childJDBCClass | grep childJDBCClass
Compiled from “childJDBCClass.java”
public class com.somepackage.jdbc.childJDBCClass extends java.lang.Object implements com.somepackage.jdbc.parentJDBCClass{
 public com.somepackage.jdbc.childJDBCClass() throws java.sql.SQLException;
 public com.somepackage.jdbc.childJDBCClass(java.lang.String, java.util.Properties) throws java.sql.SQLException;

[email protected]:lib$ javap -classpath genCorejdbc.jar com.somepackage.jdbc.childJDBCClass | grep childJDBCClass Compiled from “childJDBCClass.java” public class com.somepackage.jdbc.childJDBCClass extends java.lang.Object implements com.somepackage.jdbc.parentJDBCClass{ public com.somepackage.jdbc.childJDBCClass() throws java.sql.SQLException; public com.somepackage.jdbc.childJDBCClass(java.lang.String, java.lang.String, java.lang.String, java.util.Properties) throws java.sql.SQLException;

“The constructors are different!” Christine said.

“How’s that possible? It’s the exact same file!” Andrew cried.

They cracked open the jar on mockingbird for a sanity check- and discovered it was holding the same constructor as sesame.

Christine muttered something impolite. Andrew felt himself going cross-eyed, and questioned his place in the universe. “Where the hell is this other constructor coming from? This stupid box really is cursed!”

“No, just running a JVM,” Christine tried to reassure them both. “Come on, let’s think… a different class with the same name is getting loaded first, from…”

“Hell?” Andrew offered.

Christine frowned. “genCore doesn’t add anything to the classpath on the fly. Do you have any shell scripts on here that might be-”

“I don’t know. I just want to go back to my cube and forget all about this!” Andrew cried.

“Pull yourself together, we can’t turn back now! Google’s gotta have something!”

Christine pulled up a browser on her smartphone, holding it between them, and searched for a refresher on Java’s class loading behavior. There they discovered the most horrifying revelation of all.

“Extensions! Extensions take precedence over CLASSPATH!” Andrew said. “Compare lib/ext on both servers, quick!”

Sure enough, they found a different version of genCorejdbc.jar in mockingbirds extensions folder. Once removed, it exorcized the demons, and genCore loaded properly.

Andrew doubled over, sighing with relief. “Thank crap that’s over.”

“No, it’s not.” Christine, pale, looked to him out of the corner of her eye. “Who put that jar file there in the first place?”

A deafening peal of thunder answered her nervous question.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!