jOOQ 4.0’s New API Will Use Annotations Only for Truly Declarative Java/SQL Programming


SQL is the only really popular and mature 4GL (Fourth Generation Programming Language). I.e. it is the only popular declarative language.

At the same time, SQL has proven that turing completeness is not reserved to lesser languages like C, C++, or Java. Since SQL:1999 and its hierarchical common table expressions, SQL can be safely considered “turing complete”. This means that any program can be written in SQL. Don’t believe it? Take, for instance, this SQL Mandelbrot set calculation as can be seen in this Stack Overflow question.

mandelbrot set

Source: User Elie on http://stackoverflow.com/q/314864/521799

Wonderful! No more need for procedural, and object oriented cruft.

How we’ve been wrong so far…

At Data Geekery (the company behind jOOQ), we love SQL. And we love Java. But one thing has always bothered us in the past. Java is not really a purely declarative language. A lot of Java language constructs are real anti patterns for the enlightened declarative programmer. For instance:

// This is bad
for (String string : strings)
    System.out.println(string);

// This is even worse
try {
    someSQLStatements();
}
catch (SQLException e) {
    someRecovery();
}

The imperative style of the above code is hardly ever useful. Programmers need to tediously tell the Java compiler and the JVM what algorithm they meant to implement, down to the single statement, when in reality, using the JIT and other advanced optimisation techniques, they don’t really have to.

Luckily, there are annotations

Since Java 5, however, there have been farsighted people in expert groups who have added a powerful new concept to the Java language: Annotations (more info here). At first, experiments were made with only a handful of limited-use annotations, like:

  • @Override
  • @SuppressWarnings

But then, even more farsighted people have then proceeded in combining these annotations to form completely declaratively things like a component:

@Path("/MonsterRest")
@Stateless
@WebServlet(urlPatterns = "/MonsterServlet")
@Entity
@Table(name = "MonsterEntity")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@NamedQuery(name = "findAll", query = "SELECT c FROM Book c")
public class Book extends HttpServlet {
 
    // ======================================
    // =             Attributes             =
    // ======================================
 
    @Id
    @GeneratedValue
    private Long id;
    private String isbn;
    private Integer nbOfPage;
    private Boolean illustrations;
    private String contentLanguage;
    @Column(nullable = false)
    @Size(min = 5, max = 50)
    @XmlElement(nillable = false)
    private String title;
    private Float price;
    @Column(length = 2000)
    @Size(max = 2000)
    private String description;
    @ElementCollection
    @CollectionTable(name = "tags")
    private List<String> tags = new ArrayList<>();

Look at this beauty. Credits to Antonio Goncalves

However, we still think that there is a lot of unnecessary object oriented bloat in the above. Luckily, recent innovations that make Java annotations turing complete (or even sentient?) will now finally allow us to improve upon this situation, specifically for jOOQ, which aims to model the declarative SQL language in Java. Finally, annotations are a perfect fit!

Those innovations are:

These innovations allow us to completely re-implement the entire jOOQ 4.0 API in order to allow for users writing SQL as follows:

@Select({
    @Column("FIRST_NAME"),
    @Column("LAST_NAME")
})
@From(
    table = @Table("AUTHOR"),
    join = @Join("BOOK"),
    predicate = @On(
        left = @Column("AUTHOR.ID"),
        op = @Eq,
        right = @Column("BOOK.AUTHOR_ID")
    )
)
@Where(
    predicate = @Predicate(
        left = @Column("BOOK.TITLE"),
        op = @Like,
        right = @Value("%Annotations in a Nutshell%")
    )
)
class SQLStatement {}

Just like JPA, this makes jOOQ now fully transparent and declarative, by using annotations. Developers will now be able to completely effortlessly translate their medium to highly complex SQL queries into the exact equivalent in jOOQ annotations.

Don’t worry, we’ll provide migration scripts to upgrade your legacy jOOQ 3.x application to 4.0. A working prototype is on the way and is expected to be released soon, early adopter feedback is very welcome, so stay tuned for more exciting SQL goodness!

10 Things You Didn’t Know About Java


So, you’ve been working with Java since the very beginning? Remember the days when it was called “Oak”, when OO was still a hot topic, when C++ folks thought that Java had no chance, when Applets were still a thing?

I bet that you didn’t know at least half of the following things. Let’s start this week with some great surprises about the inner workings of Java.

1. There is no such thing as a checked exception

That’s right! The JVM doesn’t know any such thing, only the Java language does.

Today, everyone agrees that checked exceptions were a mistake. As Bruce Eckel said on his closing keynote at GeeCON, Prague, no other language after Java has engaged in using checked exceptions, and even Java 8 does no longer embrace them in the new Streams API (which can actually be a bit of a pain, when your lambdas use IO or JDBC).

Do you want proof that the JVM doesn’t know such a thing? Try the following code:

public class Test {
 
    // No throws clause here
    public static void main(String[] args) {
        doThrow(new SQLException());
    }
 
    static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }
 
    @SuppressWarnings("unchecked")
    static <E extends Exception> 
    void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}

Not only does this compile, this also actually throws the SQLException, you don’t even need Lombok’s @SneakyThrows for that.

More details about the above can be found in this article here, or here, on Stack Overflow.

2. You can have method overloads differing only in return types

That doesn’t compile, right?

class Test {
    Object x() { return "abc"; }
    String x() { return "123"; }
}

Right. The Java language doesn’t allow for two methods to be “override-equivalent” within the same class, regardless of their potentially differing throws clauses or return types.

But wait a second. Check out the Javadoc of Class.getMethod(String, Class...). It reads:

Note that there may be more than one matching method in a class because while the Java language forbids a class to declare multiple methods with the same signature but different return types, the Java virtual machine does not. This increased flexibility in the virtual machine can be used to implement various language features. For example, covariant returns can be implemented with bridge methods; the bridge method and the method being overridden would have the same signature but different return types.

Wow, yes that makes sense. In fact, that’s pretty much what happens when you write the following:

abstract class Parent<T> {
    abstract T x();
}

class Child extends Parent<String> {
    @Override
    String x() { return "abc"; }
}

Check out the generated byte code in Child:

  // Method descriptor #15 ()Ljava/lang/String;
  // Stack: 1, Locals: 1
  java.lang.String x();
    0  ldc <String "abc"> [16]
    2  areturn
      Line numbers:
        [pc: 0, line: 7]
      Local variable table:
        [pc: 0, pc: 3] local: this index: 0 type: Child
  
  // Method descriptor #18 ()Ljava/lang/Object;
  // Stack: 1, Locals: 1
  bridge synthetic java.lang.Object x();
    0  aload_0 [this]
    1  invokevirtual Child.x() : java.lang.String [19]
    4  areturn
      Line numbers:
        [pc: 0, line: 1]

So, T is really just Object in byte code. That’s well understood.

The synthetic bridge method is actually generated by the compiler because the return type of the Parent.x() signature may be expected to Object at certain call sites. Adding generics without such bridge methods would not have been possible in a binary compatible way. So, changing the JVM to allow for this feature was the lesser pain (which also allows covariant overriding as a side-effect…) Clever, huh?

Are you into language specifics and internals? Then find some more very interesting details here.

3. All of these are two-dimensional arrays!

class Test {
    int[][] a()  { return new int[0][]; }
    int[] b() [] { return new int[0][]; }
    int c() [][] { return new int[0][]; }
}

Yes, it’s true. Even if your mental parser might not immediately understand the return type of the above methods, they are all the same! Similar to the following piece of code:

class Test {
    int[][] a = {{}};
    int[] b[] = {{}};
    int c[][] = {{}};
}

You think that’s crazy? Imagine using JSR-308 / Java 8 type annotations on the above. The number of syntactic possibilities explodes!

@Target(ElementType.TYPE_USE)
@interface Crazy {}

class Test {
    @Crazy int[][]  a1 = {{}};
    int @Crazy [][] a2 = {{}};
    int[] @Crazy [] a3 = {{}};

    @Crazy int[] b1[]  = {{}};
    int @Crazy [] b2[] = {{}};
    int[] b3 @Crazy [] = {{}};

    @Crazy int c1[][]  = {{}};
    int c2 @Crazy [][] = {{}};
    int c3[] @Crazy [] = {{}};
}

Type annotations. A device whose mystery is only exceeded by its power

Or in other words:

When I do that one last commit just before my 4 week vacation

When I do that one last commit just before my 4 week vacation

I let the actual exercise of finding a use-case for any of the above to you.

4. You don’t get the conditional expression

So, you thought you knew it all when it comes to using the conditional expression? Let me tell you, you didn’t. Most of you will think that the below two snippets are equivalent:

Object o1 = true ? new Integer(1) : new Double(2.0);

… the same as this?

Object o2;

if (true)
    o2 = new Integer(1);
else
    o2 = new Double(2.0);

Nope. Let’s run a quick test

System.out.println(o1);
System.out.println(o2);

This programme will print:

1.0
1

Yep! The conditional operator will implement numeric type promotion, if “needed”, with a very very very strong set of quotation marks on that “needed”. Because, would you expect this programme to throw a NullPointerException?

Integer i = new Integer(1);
if (i.equals(1))
    i = null;
Double d = new Double(2.0);
Object o = true ? i : d; // NullPointerException!
System.out.println(o);

More information about the above can be found here.

5. You also don’t get the compound assignment operator

Quirky enough? Let’s consider the following two pieces of code:

i += j;
i = i + j;

Intuitively, they should be equivalent, right? But guess what. They aren’t! The JLS specifies:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

This is so beautiful, I would like to cite Peter Lawrey‘s answer to this Stack Overflow question:

A good example of this casting is using *= or /=

byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57

or

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

or

char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'

or

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

Now, how incredibly useful is that? I’m going to cast/multiply chars right there in my application. Because, you know…

6. Random integers

Now, this is more of a puzzler. Don’t read the solution yet. See if you can find this one out yourself. When I run the following programme:

for (int i = 0; i < 10; i++) {
  System.out.println((Integer) i);
}

… then “sometimes”, I get the following output:

92
221
45
48
236
183
39
193
33
84

How is that even possible??

.

.

.

.

.

. spoiler… solution ahead…

.

.

.

.

.

OK, the solution is here (https://blog.jooq.org/2013/10/17/add-some-entropy-to-your-jvm/) and has to do with overriding the JDK’s Integer cache via reflection, and then using auto-boxing and auto-unboxing. Don’t do this at home! Or in other words, let’s think about it this way, once more

When I do that one last commit just before my 4 week vacation

When I do that one last commit just before my 4 week vacation

7. GOTO

This is one of my favourite. Java has GOTO! Type it…

int goto = 1;

This will result in:

Test.java:44: error: <identifier> expected
    int goto = 1;
       ^

This is because goto is an unused keyword, just in case…

But that’s not the exciting part. The exciting part is that you can actually implement goto with break, continue and labelled blocks:

Jumping forward

label: {
  // do stuff
  if (check) break label;
  // do more stuff
}

In bytecode:

2  iload_1 [check]
3  ifeq 6          // Jumping forward
6  ..

Jumping backward

label: do {
  // do stuff
  if (check) continue label;
  // do more stuff
  break label;
} while(true);

In bytecode:

 2  iload_1 [check]
 3  ifeq 9
 6  goto 2          // Jumping backward
 9  ..

8. Java has type aliases

In other languages (e.g. Ceylon), we can define type aliases very easily:

interface People => Set<Person>;

A People type constructed in such a way can then be used interchangably with Set<Person>:

People?      p1 = null;
Set<Person>? p2 = p1;
People?      p3 = p2;

In Java, we can’t define type aliases at a top level. But we can do so for the scope of a class, or a method. Let’s consider that we’re unhappy with the namings of Integer, Long etc, we want shorter names: I and L. Easy:

class Test<I extends Integer> {
    <L extends Long> void x(I i, L l) {
        System.out.println(
            i.intValue() + ", " + 
            l.longValue()
        );
    }
}

In the above programme, Integer is “aliased” to I for the scope of the Test class, whereas Long is “aliased” to L for the scope of the x() method. We can then call the above method like this:

new Test().x(1, 2L);

This technique is of course not to be taken seriously. In this case, Integer and Long are both final types, which means that the types I and L are effectively aliases (almost. assignment-compatibility only goes one way). If we had used non-final types (e.g. Object), then we’d be really using ordinary generics.

Enough of these silly tricks. Now for something truly remarkable!

9. Some type relationships are undecidable!

OK, this will now get really funky, so take a cup of coffee and concentrate. Consider the following two types:

// A helper type. You could also just use List
interface Type<T> {}

class C implements Type<Type<? super C>> {}
class D<P> implements Type<Type<? super D<D<P>>>> {}

Now, what do the types C and D even mean?

They are somewhat recursive, in a similar (yet subtly different) way that java.lang.Enum is recursive. Consider:

public abstract class Enum<E extends Enum<E>> { ... }

With the above specification, an actual enum implementation is just mere syntactic sugar:

// This
enum MyEnum {}

// Is really just sugar for this
class MyEnum extends Enum<MyEnum> { ... }

With this in mind, let’s get back to our two types. Does the following compile?

class Test {
    Type<? super C> c = new C();
    Type<? super D<Byte>> d = new D<Byte>();
}

Hard question, and Ross Tate has an answer to it. The question is in fact undecidable:

Is C a subtype of Type<? super C>?

Step 0) C <?: Type<? super C>
Step 1) Type<Type<? super C>> <?: Type (inheritance)
Step 2) C  (checking wildcard ? super C)
Step . . . (cycle forever)

And then:

Is D a subtype of Type<? super D<Byte>>?

Step 0) D<Byte> <?: Type<? super C<Byte>>
Step 1) Type<Type<? super D<D<Byte>>>> <?: Type<? super D<Byte>>
Step 2) D<Byte> <?: Type<? super D<D<Byte>>>
Step 3) Type<type<? super C<C>>> <?: Type<? super C<C>>
Step 4) D<D<Byte>> <?: Type<? super D<D<Byte>>>
Step . . . (expand forever)

Try compiling the above in your Eclipse, it’ll crash! (don’t worry. I’ve filed a bug)

Let this sink in…

Some type relationships in Java are undecidable!

If you’re interested in more details about this peculiar Java quirk, read Ross Tate’s paper “Taming Wildcards in Java’s Type System” (co-authored with Alan Leung and Sorin Lerner), or also our own musings on correlating subtype polymorphism with generic polymorphism

10. Type intersections

Java has a very peculiar feature called type intersections. You can declare a (generic) type that is in fact the intersection of two types. For instance:

class Test<T extends Serializable & Cloneable> {
}

The generic type parameter T that you’re binding to instances of the class Test must implement both Serializable and Cloneable. For instance, String is not a possible bound, but Date is:

// Doesn't compile
Test<String> s = null;

// Compiles
Test<Date> d = null;

This feature has seen reuse in Java 8, where you can now cast types to ad-hoc type intersections. How is this useful? Almost not at all, but if you want to coerce a lambda expression into such a type, there’s no other way. Let’s assume you have this crazy type constraint on your method:

<T extends Runnable & Serializable> void execute(T t) {}

You want a Runnable that is also Serializable just in case you’d like to execute it somewhere else and send it over the wire. Lambdas and serialisation are a bit of a quirk.

Lambdas can be serialised:

You can serialize a lambda expression if its target type and its captured arguments are serializable

But even if that’s true, they do not automatically implement the Serializable marker interface. To coerce them to that type, you must cast. But when you cast only to Serializable

execute((Serializable) (() -> {}));

… then the lambda will no longer be Runnable.

Egh…

So…

Cast it to both types:

execute((Runnable & Serializable) (() -> {}));

Conclusion

I usually say this only about SQL, but it’s about time to conclude an article with the following:

Java is a device whose mystery is only exceeded by its power

Found this article interesting?

How about this one: 10 Subtle Best Practices when Coding Java

The dreaded DefaultAbstractHelperImpl


A while ago, we have published this fun game we like to call Spring API Bingo. It is a tribute and flattery to Spring’s immense creativeness when forming meaningful class names like

  • FactoryAdvisorAdapterHandlerLoader
  • ContainerPreTranslatorInfoDisposable
  • BeanFactoryDestinationResolver
  • LocalPersistenceManagerFactoryBean

Two of the above classes actually exist. Can you spot them? If no, play Spring API Bingo!

Clearly, the Spring API suffers from having…

To name things

There are only two hard problems in computer science. Cache invalidation, naming things, and off-by-one errors

– Tim Bray quoting Phil Karlton

There are a couple of these prefixes or suffixes that are just hard to get rid of in Java software. Consider this recent discussion on Twitter, that inevitably lead to an (very) interesting discussion:

Yes, the Impl suffix is an interesting topic. Why do we have it, and why do we keep naming things that way?

Specification vs. body

Java is a quirky language. At the time it was invented, object orientation was a hot topic. But procedural languages had interesting features as well. One very interesting language at the time was Ada (and also PL/SQL, which was largely derived from Ada). Ada (like PL/SQL) reasonably organises procedures and functions in packages, which come in two flavours: specification and body. From the wikipedia example:

-- Specification
package Example is
  procedure Print_and_Increment (j: in out Number);
end Example;

-- Body
package body Example is
 
  procedure Print_and_Increment (j: in out Number) is
  begin
    -- [...]
  end Print_and_Increment;
 
begin
  -- [...]
end Example;

You always have to do this, and the two things are named exactly the same: Example. And they’re stored in two different files called Example.ads (ad for Ada and s for specification) and Example.adb (b for body). PL/SQL followed suit and names package files Example.pks and Example.pkb with pk for Package.

Java went a different way mainly because of polymorphism and because of the way classes work:

  • Classes are both specification AND body in one
  • Interfaces cannot be named the same as their implementing classes (mostly, because there are many implementations, of course)

In particular, classes can be a hybrid of spec-only, with a partial body (when they’re abstract), and full spec and body (when they’re concrete).

How this translates to naming in Java

Not everyone appreciates clean separation of specs and body, and this can certainly be debated. But when you’re in that Ada-esque mind set, then you probably want one interface for every class, at least wherever API is exposed. We’re doing the same for jOOQ, where we have established the following policy to name things:

*Impl

All implementations (bodies) that are in a 1:1 relationship with a corresponding interface are suffixed Impl. If ever possible, we try to keep those implementations package-private and thus sealed in the org.jooq.impl package. Examples are:

This strict naming scheme makes it immediately clear, which one is the interface (and thus public API), and which one is the implementation. We wish Java were more like Ada with this respect, but we have polymorphism, which is great, and…

Abstract*

… and it leads to reusing code in base classes. As we all know, common base classes should (almost) always be abstract. Simply because they’re most often incomplete implementations (bodies) of their corresponding specification. Thus, we have a lot of partial implementations that are also in a 1:1 relationship with a corresponding interface, and we prefix them with Abstract. Most often, these partial implementations are also package-private and sealed in the org.jooq.impl package. Examples are:

In particular, ResultQuery is an interface that extends Query, and thus AbstractResultQuery is a partial implementation that extends the AbstractQuery, which is also a partial implementation.

Having partial implementations makes perfect sense in our API, because our API is an internal DSL (Domain-Specific Language) and thus has thousands of methods that are always the same, no matter what the concrete Field really does – e.g. Substring

Default*

We do everything API related with interfaces. This has proven highly effective already in popular Java SE APIs, such as:

  • Collections
  • Streams
  • JDBC
  • DOM

We also do everything SPI (Service Provider Interface) related with interfaces. There is one essential difference between APIs and SPIs in terms of API evolution:

  • APIs are consumed by users, hardly implemented
  • SPIs are implemented by users, hardly consumed

If you’re not developing the JDK (and thus don’t have completely mad backwards-compatibility rules), you’re probably mostly safe adding new methods to API interfaces. In fact, we do so in every minor release as we do not expect anyone to implement our DSL (who’d want to implement Field‘s 286 methods, or DSL‘s 677 methods. That’s mad!)

But SPIs are different. Whenever you provide your user with SPIs, such as anything suffixed *Listener or *Provider, you can’t just simply add new methods to them – at least not prior to Java 8, as that would break implementations, and there are many of them.

Well. We still do it, because we don’t have those JDK backwards-compatibility rules. We have more relaxed ones. But we suggest our users do not implement the interfaces directly themselves, but extend a Default implementation instead, which is empty. For instance ExecuteListener and the corresponding DefaultExecuteListener:

public interface ExecuteListener {
    void start(ExecuteContext ctx);
    void renderStart(ExecuteContext ctx);
    // [...]
}

public class DefaultExecuteListener
implements ExecuteListener {

    @Override
    public void start(ExecuteContext ctx) {}

    @Override
    public void renderStart(ExecuteContext ctx) {}

    // [...]
}

So, Default* is a prefix that is commonly used to provide a single public implementation that API consumers can use and instantiate, or SPI implementors can extend – without risking backwards-compatibility issues. It’s pretty much a workaround for Java 6 / 7’s lack of interface default methods, which is why the prefix naming is even more appropriate.

Java 8 Version of this rule

In fact, this practice makes it evident that a “good” rule to specify Java-8 compatible SPIs is to use interfaces and to make all methods default with an empty body. If jOOQ didn’t support Java 6, we’d probably specify our ExecuteListener like this:

public interface ExecuteListener {
    default void start(ExecuteContext ctx) {}
    default void renderStart(ExecuteContext ctx) {}
    // [...]
}

*Utils or *Helper

OK, so here’s one for the mock/testing/coverage experts and aficionados out there.

It’s TOTALLY OK to have a “dump” for all sorts of static utility methods. I mean, of course you could be a member of the object-orientation police. But…

Please. Don’t be “that guy”! 🙂

So, there are various techniques of identifying utility classes. Ideally, you take a naming convention and then stick to it. E.g. *Utils.

From our perspective, ideally you’d even just dump all utility methods that are not stricly bound to a very specific domain in a single class, because frankly, when did you last appreciate having to go through millions of classes to find that utility method? Never. We have org.jooq.impl.Utils. Why? Because it’ll allow you to do:

import static org.jooq.impl.Utils.*;

This then almost feels as if you had something like “top-level functions” throughout your application. “global” functions. Which we think is a nice thing. And we totally don’t buy the “we can’t mock this” argument, so don’t even try starting a discussion

Discussion

… or, in fact, let’s do start a discussion. What are your techniques, and why? Here are a couple of reactions to Tom Bujok’s original Tweet, to help get you started:

Let’s go 😉

This Just In!! Updated Silly Keyword Metrics


It’s this time of the year and we’re repeating the silly metrics keyword count across all of jOOQ‘s code base.

We have a couple of exciting news! public is still one of the favourite keywords (yeah, we’re an API), but return is closing in, as well as final (yeah, we love final).

A bit more surprising:

  • if has surpassed throws and void. Is jOOQ becoming less object oriented, and more imperative?
  • true is still more popular than false. Yeah, we’re thinking positively about life
  • continue has one more instance in our code base. Gotta love the occasional continue!
  • do experienced a 600% increase!
  • … we still try more than we catch
  • … does the rise of char mean that we’re parsing more SQL?
  • … and we’ve removed one instance of volatile
  • … and still no strictfp or native
2013                2014                   
--------------------------------------
Keyword      Count  Keyword      Count     
public       8127   public       9379      
return       6801   return       8079      
final        6608   final        7561      
import       5938   import       7232      
static       3903   static       5154      
new          3110   new          3915      
extends      2111   extends      2884      
int          1822   int          2132      
throws       1756   if           1985      
void         1707   throws       1898      
if           1661   void         1834      
this         1464   this         1803      
private      1347   private      1605      
class        1239   class        1437      
case         841    case         1225      
else         839    else         940       
package      711    package      842       
boolean      506    boolean      623       
throw        495    throw        553       
for          421    for          469       
long         404    long         456       
true         384    true         439       
byte         345    interface    407       
interface    337    byte         397       
false        332    false        396       
protected    293    break        357       
super        265    protected    328       
break        200    super        328       
try          149    switch       197       
switch       146    try          193       
implements   139    catch        167       
catch        127    implements   162       
default      112    default      156       
instanceof   107    instanceof   156       
char         96     char         122       
short        91     short        93        
abstract     54     finally      54        
double       43     abstract     50        
transient    42     transient    45        
finally      34     double       44        
float        34     float        35        
enum         25     while        35        
while        23     enum         31        
continue     12     continue     13        
synchronized 8      synchronized 10        
volatile     6      do           6         
do           1      volatile     5  

Download the free and ASL 2.0 licensed “silly-metrics” program and start counting keywords in your software.

Why You Should NOT Implement Layered Architectures


Abstraction layers in software are what architecture astronauts tell you to do. Instead, however, half of all applications out there would be so easy, fun, and most importantly: productive to implement if you just got rid of all those layers.

Frankly, what do you really need? You need these two:

  • Some data access
  • Some UI

Because that’s the two things that you inevitably have in most systems. Users, and data. Here’s Kyle Boon’s opinion on possible choices that you may have

Very nice choice, Kyle. Ratpack and jOOQ. You could choose any other APIs, of course. You could even choose to write JDBC directly in JSP. Why not. As long as you don’t go pile up 13 layers of abstraction:

That’s all bollocks, you’re saying? We need layers to abstract away the underlying implementation so we can change it? OK, let’s give this some serious thought. How often do you really change the implementation? Some examples:

  • SQL. You hardly change the implementation from Oracle to DB2
  • DBMS. You hardly change the model from relational to flat or XML or JSON
  • JPA. You hardly switch from Hibernate to EclipseLink
  • UI. You simply don’t replace HTML with Swing
  • Transport. You just don’t switch from HTTP to SOAP
  • Transaction layer. You just don’t substitute JavaEE with Spring, or JDBC transactions

Nope. Your architecture is probably set in stone. And if – by the incredible influence of entropy and fate – you happen to have made the wrong decision in one aspect, about 3 years ago, well you’re in for a major refactoring anyway. If SQL was the wrong choice, well good luck to you migrating everything to MongoDB (which is per se the wrong choice again, so prepare for migrating back). If HTML was the wrong choice, well even more tough luck to you. Likelihood of your layers not really helping you when a concrete incident happens: 95% (because you missed an important detail)

Layers = Insurance

If you’re still thinking about implementing an extremely nice layered architecture, ready to deal with pretty much every situation where you simply switch a complete stack with another, then what you’re really doing is filing a dozen insurance policies. Think about it this way. You can get:

  • Legal insurance
  • Third party insurance
  • Reinsurance
  • Business interruption insurance
  • Business overhead expense disability insurance
  • Key person insurance
  • Shipping insurance
  • War risk insurance
  • Payment protection insurance
  • pick a random category

You can pay and pay and pay in advance for things that probably won’t ever happen to you. Will they? Yeah, they might. But if you buy all that insurance, you pay heavily up front. And let me tell you a secret. IF any incident ever happens, chances are that you:

  • Didn’t buy that particular insurance
  • Aren’t covered appropriately
  • Didn’t read the policy
  • Got screwed

And you’re doing exactly that in every application that would otherwise already be finished and would already be adding value to your customer, while you’re still debating if on layer 37 between the business rules and transformation layers, you actually need another abstraction because the rule engine could be switched any time.

Stop doing that

You get the point. If you have infinite amounts of time and money, implement an awesome, huge architecture up front.

Your competitor’s time to market (and fun, on the way) is better than yours. But for a short period of time, you were that close to the perfect, layered architecture!

Top 10 Very Very VERY Important Topics to Discuss


Some things are just very very very VERY very important. Such as John Cleese.

The same is true for Whitespace:

Yes. 1080 Reddit Karma points (so urgently needed!) in only 23 hours. That’s several orders of magnitudes better than any of our – what we wrongfully thought to be – very deep and interesting technical insight about Java and SQL has ever produced.

The topic of interest was a humourous treatise about whether this:

for (int i=0; i<LENGTH; i++)

… or this:

for (int i = 0; i < LENGTH; i++)

… should be preferred. Obviously both options are completely wrong. The right answer is:

for 
(   int i = 0
;   i < LENGTH
;   i++
)

Read the full treatise here.

But at some point, the whitespace discussion is getting stale. We need new very very very important topics to discuss instead of fixing them bugs. After all, the weekend is imminent, and we don’t know what else to talk about.

This is why we are now publishing…

Top 10 Very Very VERY Important Topics to Discuss

Here we go…

0. Whitespace

OK, that was a no-brainer. We’ve already had that. Want to participate? The very interesting Reddit discussion is still hot.

1. The Vietnam of Computer Science

In case you haven’t heard of this highly interesting discussion, there are some people who believe that ORMs are outdated, because ORMs don’t work as promised. And they’re totally right. And the best thing is, all the others are totally right as well.

Why is that great? Because that means we get to discuss it. Endlessly!

While everyone keeps talking about ORMs like that, no one cares what Gavin King (creator of Hibernate) had said from the beginning:

Why should we care about his opinion? We have our own, far superior opinion! Let’s have another discussion about why ORMs are evil!

2. Case-sensitivity

Unfortunately, us Java folks cannot have any of those very very very very very important discussions about casing, because unfortunately, Java is a case-sensitive language.

But take SQL (or PL/SQL, T-SQL for that sake). When writing SQL, we can have awesome discussions about whether we should

-- Upper case it all
SELECT TAB.COL1, TAB.COL2 FROM TAB

-- Upper case keywords, lower case identifiers
SELECT tab.col1, tab.col2 FROM tab

-- Lower case keywords, upper case identifiers
select TAB.COL1, TAB.COL2 from TAB

-- Lower case it all
select tab.col1, tab.col2 from tab

-- Add some PascalCase (awesome SQL Server!)
SELECT Tab.Col1, Tab.Col2 FROM Tab

-- Mix case-sensitivity with case-insensitivity
-- (Protip to piss off your coworkers: Name your
-- table "FROM" or "INTO" and let them figure out
-- how to query that table)
SELECT TAB."COL1", TAB."col2" FROM "FROM"

-- PascalCase keywords (wow, MS Access)
Select TAB.COL1, TAB.COL2 From TAB

Now that is really incredibly interesting. And because this is so interesting and important, you can only imagine the number of interesting discussions we’ve had on the jOOQ User Group, for instance, about how to best generate meta data from the database. With jOOQ, we promise that you can extend these enticing discussions from the SQL area to the Java area by overriding the code generator’s default behaviour:

  • Should classes be PascalCased and literals be UPPER_CASED?
  • Should everything be PascalCased and camelCased as in Java?
  • Should everything be generated as named in the database?

Endless interesting discussions!

jOOQ: The Best Way to Write SQL in Java

We have so many options to SQL casing, which brings us to

3. SQL formatting

Unlike C-style general-purpose languages such as C, Java, Scala, C#, or even keyword-heavy ones Delphi, Pascal, Ada, SQL has one more awesome grounds for numerous discussions. It is not only keyword-heavy, but it also has a very complex and highly irregular syntax. So we’re lucky enough to get to choose (after long discussions and settlements) between:

-- All on one line. Don't tell me about print margins,
-- Or I'll telefax you my SQL!
SELECT table1.col1, table1.col2 FROM table1 JOIN table2 ON table1.id = table2.id WHERE id IN (SELECT x FROM other_table)

-- "Main" keywords on new line
SELECT table1.col1, table1.col2 
FROM table1 JOIN table2 ON table1.id = table2.id 
WHERE id IN (SELECT x FROM other_table)

-- (almost) all keywords on new line
SELECT table1.col1, table1.col2 
FROM table1 
JOIN table2 
ON table1.id = table2.id 
WHERE id IN (SELECT x FROM other_table)

-- "Main" keywords on new line, others indented
SELECT table1.col1, table1.col2 
FROM table1 
  JOIN table2 
  ON table1.id = table2.id 
WHERE id IN (
  SELECT x 
  FROM other_table
)

-- "Main" keywords on new line, others heavily indented
SELECT table1.col1, table1.col2 
FROM table1 JOIN table2 
              ON table1.id = table2.id 
WHERE id IN (SELECT x 
             FROM other_table)

-- Doge formatting
SUCH table1.col1,
                 table1.col2
    MUCH table1
JOIN table2 WOW table1.id
            = table2.id
WHICH              id IN
   (SUCH x

WOW other_table
            )
Doge SQL Formatting

Doge SQL Formatting

And so on and so forth. Now any project manager should reserve at least 10 man-weeks in every project to agree on rules about SQL formatting.

4. The end of the DBA

Now THAT is a very interesting topic that is not only interesting for developers who are so knowledgeable about productive systems, no it’s also very interesting for operations teams. Because as we all know, the DBA is dead (again).

For those of you who have been missing out on this highly interesting topic, do know that all of this started (again) when the great NoSQL vs. SQL debate was initiated by brilliant minds and vendors of truly alternative systems. Which are now starting to implement SQL, because apparently, well… SQL isn’t all that bad:

Please, do engage in some more discussions about the best and only true way to tackle database problems. Because your opinion counts!

5. New lines and comments

Remember our own blog post about putting some keywords on new lines? Yes, we prefer:

// If this
if (something) {
    ...
}

// Else something else
else {
    ...
}

Exactly. Because this allows comments to be written where they belong: Next to the appropriate keyword, and always aligned at the same column. This leads us to the next very interesting question: Should we put comments in code at all? Or is clean code self-documenting?

And we say, why yes, of course we should comment. How on earth will anyone ever remember the rationale behind something like this??

// [#2744] DB2 knows the SELECT .. FROM FINAL 
// TABLE (INSERT ..) syntax
case DB2:

// Firebird and Postgres can execute the INSERT 
// .. RETURNING clause like a select clause. JDBC
// support is not implemented in the Postgres JDBC
// driver
case FIREBIRD:
case POSTGRES: {
    try {
        listener.executeStart(ctx);
        rs = ctx.statement().executeQuery();
        listener.executeEnd(ctx);
    }
    finally {
        consumeWarnings(ctx, listener);
    }

    break;
}

Taken from our “hacking JDBC” page.

6. JSON is totally better than XML

Of course it is! Because… because… errr. Because it allows me to structure data hierarchically. Waaaait a second…

Dayum.

You’re saying, JSON and XML are the SAME THING!?

But MongoDB and PostgreSQL allow me to store JSON. Oh wait. They tried to store XML in databases, back in the 90s, too!? And it failed? Well, of course it failed, because XML sucks, right? (which is essentially another way of saying that I’ve never understood XSLT or XQuery or XPath or didn’t even hear about XProc, and I’m just ranting about angle brackets and namespaces)

Let’s further discuss this matter. I feel that we’re close to the very ultimate solution on that topic.

Speaking of JSON…

7. Curly braces

OMG! This is the most interesting of all topics. Should we put the opening brace:

  • On the same line?
  • On a NEW line??
  • NO BRACE AT ALL???

The right answers are 1) and 3). 1) only if we absolutely have to, as in try or switch statements. We’re not paid by the number of lines of code, so we don’t add meaningless lines with only opening braces. And if we can omit the braces entirely, fine. Here’s an awesome statement, if you ask me:

if (something)
    outer:
    for (String thing : list)
        inner:
        do
            if (somethingElse)
                break inner;
            else
                continue outer;
        while (true);

That ought to teach them juniors not to touch my code. Which brings us to:

8. Labels

Nothing wrong with them. I’ll break out of my loops any time I want. Don’t tell me labels are Java’s way of saying GOTO, they’re much more sophisticated than that. (Besides, goto is a reserved word in Java, and it is an actual bytecode instruction). So I’ll happily do my jumping forward:

label: {
  // do stuff
  if (check) break label;
  // do more stuff
}

Or my jumping backward:

label: do {
  // do stuff
  if (check) continue label;
  // do more stuff
  break label;
} while(true);

(observe how the above example used two spaces for indentation instead of four (or tabs). Another great topic for further discussion)

9. emacs vs. vim vs. vi vs. Eclipse vs. IntelliJ vs. Netbeans

Can we please, PLEASE, have another very interesting discussion about which one of these is better? Please!

10. Last but not Least: Is Haskell better than [your language]?

According to TIOBE, Haskell ranks 38.

And as we all know, the actual market share (absolutely none in the case of Haskell) of any programming language is inversely proportional to the amount of time spent on reddit discussing the importance of said language, and how said language is totally superior to the one ranking 1-2 above on TIOBE, for instance. Which would be Lua.

So, I would love to invite you to join our blogging friends below to a very very interesting discussion about…

Now, of course, we could enlargen the debate and compare functional programming with OO programming in general before delving into why Scala is NOT a functional programming language, let alone Java 8.

Oh, and you think your dialect of Haskell or Lisp is not good enough, so you should roll your own? Go ahead (right after checking this checklist!)

Such great topics. So little time.

Conclusion

The great thing about these social networks like Reddit, Hackernews, and all the others is the fact that we can finally spend all day to discuss really really intersting topics instead of fixing them boring bugs our boss wants us to fix. After all, this is IMPORTANT.

Or as Randall Munroe would say: “Duty calls!”

Further reading

If you’re now all hot and ready to discuss things, please consider also reading these very interesting and insightful articles on how to best format and style code:

Or add your own. There’s still much much important writing to do!

What Big Data Really Is


One for the weekend: Big Data