What Have I Been Doing?
Code Obfuscation: Anonymous Inner Class Death
Java, like most other modern languages, will let you get away with some really ugly code. Inspired by my recent gaze into GWT generated JavaScript, I decided to crank out this little gem. I’ve pretty formatted it here because it doesn’t need any assistance to confuse from lack of white space. See if you can figure out what it does and, more importantly, how it does it.
new Object() {
public void eval(int i) {
if (new Object() {
public boolean eval(int i) {
return i == new Object() {
public int getSomeNumber() {
return 1000;
}
}.getSomeNumber();
}
}.eval(i))
return;
System.out.println(String.format("%c", i));
this.eval(new Object() {
public int next(int i) {
return i + new Object() {
public int leap() {
return 1;
}
}.leap();
}
}.next(i));
}
}.eval(0);
Take a moment and really drink this in. Its fairly simple to obfuscate just about any simple algorithm using this terrible approach. I don’t even want to think about what this is doing to the JVM’s memory, let alone mine.
Suggested Reading: Programming
Today I have a few goodies for you. The first a well thought out response to the increasing complexity of PHP frameworks. The second, a now well known reactionary response to the evolution of software engineering and project management methodologies.
PHP has been around for quite some time. As an open source programming / scripting language that snaps into the world’s most popular open source web server, it is easy to see why it has become the world’s most popular web application platform. With its absolutely massive developer community, rich documentation and examples and tutorials abound it also happens to be one of the easiest languages to learn. With this low learning curve, you can get into PHP rapidly and start cranking out all kinds of strange things with security issues you have never even imagined. People see this problem as well as issues with repetitious code and they tend to gravitate toward application frameworks. Over time these frameworks, beloved to their users grow and grow. ”Now it can do everything!” an excited user base will chant. But what they tend to not see so well is that as these frameworks grow, their barrier to entry skyrockets. The conversations go from, “Hey you should try this tool out. Its easy and reduces the code you have to write.” to, “In order to do that you should do, this… Make use of that pattern… Oh, you’re not supposed to use it that way… ” Funkatron posed their response quite eloquently at http://funkatron.com/posts/the-microphp-manifesto.html. Are thin frameworks too much to ask? I’d say that most things start thin, but rarely remain so for long.
Application design and programming are both something I like to call creative engineering. They are both also active processes. These activities tend to appeal to a certain type of person. A person who gets excited building things. Someone who demands results. They do not write code for the satisfaction of sitting in front of a computer for days on end or for the ever fulfilling notion of growing their asses. These are a means to an end, some deterministic result. We grow up in a self driven, wholly unstructured environment where we learn how to externalize ideas, turn tasks into algorithms and really create from our own Will. Then it happens. Grow into a world where we work with other people, and we all work for someone else. The creative engineering process meets communication constraints and business expectations. Rarely does it happen that any one person can understand all three worlds of thought. In recent years we have all witnessed the world of project management and software engineering practices evolve more rapidly than ever before. The shortfalls of every step in that evolution have both helped to shape the next evolution and further soured everyone involved. I’m willing to state that I’m rather optimistic about the whole thing these days. In my opinion things are a world better than they have been in the past, and that I would do anything to keep from reliving the dark days where management and engineers were separated by an anoxic barrier of mistrust and contempt. For those with a more purist view Zed A. Shaw presents to you, an alternative project management and software engineering practices philosophy, Programming Motherfucker (http://programming-motherfucker.com/). Its both humorous and a pointed counter movement of creative engineers who are tired of elongating the process to get to their precious results. Who can blame them. While managers and executives measure the cost of development in man months, they measure it in ass growth. Who do you think is more motivated to finish a project?
GWT can be Magical
The person or people responsible for the following must either be much more knowledgeable than I about JavaScript if statements, or simply more sinister. While pretty compiling one of my GWT modules today, I decided to take a peek at the generated source. As I was scrolling through the the module, my coworker pointed something out. This is what I found:
if (function(){
return ua.indexOf('msie') != -1 && $doc_0.documentMode >= 8;
}
())
return 'ie8';
if (function(){
var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
if (result && result.length == 3)
return makeVersion(result) >= 6000;
}
())
return 'ie6';
After a few moments with a baffled expression on my face, he made the announcement that he would henceforth be performing all conditional expression evaluations within anonymous functions. I couldn’t agree more. I mean, what better way to mess with the person who will be reviewing, or worse yet, supporting your code? Now, I see what they did there in the IE 6 test. Quite the cleaver hack. Kinda. But to use the same mechanism for the IE8 test is just plain strange. Does anyone have a reason why this pattern might be desirable? I’ve since taken an oath to refrain from examining the generated crap, no matter how pretty it may proclaim to be, until I’ve come a bit further in my GWT mastery.
Dear Arizona: This is Moss
Mailing List Question: @Autowired Ambiguities
Today a question went out on a Spring mailing list asking about @Autowired dependencies, AOP proxies, and interfaces. I thought this was a great foundation question. So I thought I’d share it here.
Say you have a bean class, Foo which implements FooInterface. On top of that, the bean is advised via Spring AOP it is the proxy class which is referenced by the context (IOC). Now, let’s say you want to autowire that dependency in another bean. So you mark the Foo field @Autowired. You fire up you application. Much to your dismay, you’ll get an error message on context initialization which goes something like, “unsatisfied dependency.” This is due to the fact that you are trying to autowire an object by its class but that class has been proxied. Meaning that there are no beans of this type in context.
So, you remember that its a great idea to code against interfaces rather than concrete classes. So you adjust your field type to FooInterface and fire up the application again. Unfortunately, you forgot that there are several instances of FooInterface in context and you get another error on startup. “No unique bean of type…”
So how would I autowire a specific bean out of a set? The answer is the handy @Qualifier annotation. Adding this to your autowired field let’s you specify the bean id/name to inject. In this case you’d use something like @Qualifier(“stevesFoo”). Boom. Done.
Suggested Reading
In the last few months, there have been quite a few really great articles floating around about being a software engineer, getting hired, self-promotion and strengths and weaknesses of a few major companies. Not being one to typically pay much attention to the blag-a-sphere, I’ve been caught pleasantly surprised. Check them out.
In “Don’t Call Yourself a Programmer” Patrick McKenzie writes to politely thrust unsuspecting college aged “Computer Scientists” into the real world. Letting them know just what does and doesn’t matter. He does a great job pointing out a few shortcomings of higher education and the people who have experienced little else. It is an important piece of perspective, sprinkled with a few great tips.
In Patrick’s article he references a few others, one of which really resonated with what I have observed. ”FizzBizz” by Jeff Atwood, describes the pain of finding Software Engineers that are capable of coding. I realize that this one has been around for a while, but its new to me, so its possible that you haven’t read it either. If you’re in a position to hire Software Engineers, read it.
The final article is, now famously known as “Steve’s Rant” (re-posted here). A decent tirade about the development, product, platform vision at companies including Amazon.com, Apple, Facebook, Microsoft and Google. It’s a rant, but Steve does a pretty good job of pointing that out.
Desert Code Camp Fall 2011
I’ll be attending Desert Code Camp tomorrow (today). The event will be going from about 9 to like 4:30pm. I’m going to be presenting on Spring Data JPA. Just a volunteer thing. Anyway, I built a presentation here using Prezi.com. Its a pretty sweet service. I also threw together a bit of a demo and posted it on github. Its nothing much, but contains a working example of using Spring Data JPA with general repos along with Specifications. Check it out.
Ditching JCL for SLF4J
When discussing these two logging API’s it really comes down to dynamic discovery vs. statically bound bridging mechanisms. As Ceki Gülcü wrote in his 2009 article detailing the problems with JCL:
Class loading problems encountered when using JCL fall into three main categories:
- Type-I: A
java.lang.NoClassDefFoundErrorthrown when a class is inaccessible from a parent class loader even if the said class is available to a child class loader- Type-II: Assignment incompatibility of two classes loaded by distinct class loaders, even in case where the two classes are bit-wise identical.
- Type-III: Holding references to a given class loader will prevent the resources loaded by that class loader from being garbage collected.
The article goes on to provide highly detailed descriptions of the problem while including code samples demonstrating the bugs in action.
Well, it turns out that on seeing these problems with the JCL, the good people on the log4j project decided to go another direction and create the Simple Logging Facade for Java (SLF4J) project. From the SLF4J site:
The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time.
What does it do?
SLF4J provides logging related interface to code against. By doing so, the resultant code is implementation agnostic and has only a single build-time dependency (the SLF4J library). Implementations are specified by runtime classpath configuration. The inclusion of a single library either bridging to a specific logging framework (log4j, JUL, or even JCL) or a direct implementation such as Logback will trigger the use of that implementation by SLF4J’s static binding mechanism. Finally, this API provides parameterized logging which improve performance.
How does this work?
Well, I’m summarizing here but, the core of the static binding code works by discovering implementations of org.slf4j.impl.StaticLoggerBinder on the application classpath. This magic is done in the LoggerFactory. Specifically at:
private final static void bind() {
try {
// the next line does the binding
StaticLoggerBinder.getSingleton();
...
StaticLoggerBinder classes provided by SLF4J bridges or implementations tie the API to the concrete frameworks. Here’s an example in Logback.
Just Use It
Coding against SLF4J will make your life a bit easier. Bridges erode excuses based on inheriting logging frameworks from your dependencies. Projects can freely float between logging implementations as capability and configuration requirements change. To quote Ceki Gülcü, “In summary, statically bound discovery provides better functionality, with none of the painful bugs associated with JCL’s dynamic discovery.”



















