about 1 month ago

Or what-if-a-fucking-meteor-falls-down-and-swaps-1s-and-0s

Worst atrocities has been committed in the name of future-proof.

Hey, let's refactor this previously readable code using all design patterns we can find, so that, you know, what if somebody would want to add things in the future?

Ah, the dreaded "what if": it's easy to propose, hard to fight against, and thus the team usually gives up after several what-ifs and just nods their heads. In the better case those what-ifs are kept at the bottom of the backlog; the manager is satisfied and the code is not polluted. In the worst case they are actually implemented, twisting the code base into a spaghetti of undecypherable patterns.

The best future-proof strategy I've seen so far is to keep the code simple and understandable. If the code is simple, then any requirement is easy to integrate. You must thus strive to not to be future-proof, otherwise you will trade code readability immediately for some dubious future which may not even come. Remember: complexity kills, and it's easy to introduce complexity but hard to get rid of it.

I have just recently read parts of the Code Change book by Uncle Bob (he uses that nickname himself, so I will too). Ironically dubbed A Handbook of Agile Software Craftmanship, the book is infected with the what-if fallacy and it proposes to trade code simplicity for uncertain future. For example, the Sql class on page 147:

public class Sql {
  public Sql(String table, Column[] column);
  public String create();
  public String insert(Object[] fields);
  public String selectAll();
  public String findByKey(String keyColumn, String keyValue);
  public String select(Column column, String pattern);
  public String select(Criteria criteria);
  public String preparedInsert();
  ...
}

What's wrong with this class? Absolutely nothing! It actually looks like an EntityManager. It is simple to use, auto-completion works and offers a reasonable set of utility methods. Yet Uncle Bob claims that it violates Single Responsibility Principle and proposes the following 'solution':

abstract public class Sql {
  public Sql(String table, Column[] column);
  abstract public String generate();
}
public class CreateSql extends Sql {
  public CreateSql(String table, Column[] columns)
  @Override public String generate()
}
public class SelectSql extends Sql {
  public SelectSql(String table, Column[] columns)
  @Override public String generate()
}
public class InsertSql extends Sql {
  public InsertSql(String table, Column[] columns)
  @Override public String generate()
}
public class SelectWithCriteriaSql extends Sql {
  public SelectWithCriteriaSql(String table, Column[] columns, Criteria criteria)
  @Override public String generate()
}
public class FindByKeySql extends Sql {
  public SelectWithCriteriaSql(String table, Column[] columns, String keyColumn, String keyValue)
  @Override public String generate()
}

Uncle Bob claims that

The code in each class becomes excruciatingly simple.

Wow, you have just fucked up the client API completely by scattering it into a bunch of undiscoverable classes, adding useless inheritance complexity, and you call that an improvement. Sure, go ahead and refactor your innard private classes as you see fit, I don't care as long as you give me the single Sql class to work with! Even more hilarious,

Equally important, when it's time to add the update statements, none of the existing classes need change!

Oh, awesome! The number of the SQL language statements has not been changed for 30 years, but let's be future-proof here because what if five completely new statements were suddenly invented?

This points out one of the tragedies of the Java world quite nicely. We have a simple problem, so let's invent a fucking framework around it which will "solve" an entire class of problems, complicating the world around in the process. The True Academic Way (tm) - I Don't Care About Usability As Long As I Have My Thesis.

How DI Was Invented - The Ironic Version

The problem with Java 1.3: it was really dumb and tedious to do DB transactions:

void accomodate(Guest guest) {
  startDbTransaction();
  try {
    sql.insert(guest);
  } catch(Exception ex) {
    rollbackDbTransaction();
  } finally {
    commitDbTransaction();
  }
}

Then some ingenious guy discovered that proxy interfaces could do that for us. But just having a single DB.wrap(interface) call was deemed too simple, too particular, not abstract enough and thus improper for a true academic soul, and thus a "proper" solution (read enterprise-fucking-level complicated solution) was invented by some smartass: the XML+AOP Java solution.

But there is no way to simply instantiate an interface, you need to instantiate a class implementing that interface, then remember to pass it to DB.wrap etc. This is obviously considered error-prone (because what if somebody forgets to call DB.wrap, right?) and thus it's obviously better to declare the construction chain in XML (because that's not error-prone at all). And thus we have wounded up with combining services (aka programming a pipeline of functionality) in XML.

Alas, the Dependency Injection was born, giving birth to Spring and JavaEE. All that simply because this Kotlin code:

db {
  doStuff()
}

was too much pain to write in a chatty Java 1.3, and because the thinking of Java guys is perverted with complexity.

Luckily, Oracle is dropping JavaEE, so that's one monstrosity down the drain; also Node.js without this DI nonsense (but with its own class of issues) is gaining momentum. Will we live to see a world without Spring and Java, but with Kotlin and a simple approach one day?

 
3 months ago

Once a project leaves the rapid development phase and enters the calm waters of maintanenance mode, the programming paradigm changes. Fancy hyped frameworks favored by project creators no longer play important role. What matters most now is the code readability and understandability. The code is already written - now it is going to be read, understood and fixed. After all, that's usually what happens to the code - it is written once but read by many. This is true both for open-source, but also for closed-source: people in the team come and go, and new team members need to read the code, to familiarize themselves with it.

So far I have came up with the following main principle of project maintenance:

  • You must be able to understand what the program does, without having to run it

When fixing bugs originated from production, you often don't have the possibility to reproduce the bug in your testing environment - the production usually contains a different set of users, different data, the workflow to reproduce the bug may not be clear, etc. The only things you actually have are: a log file, a stacktrace, a vague description from the user on what she did and how she interacted with the app, and perhaps a screenshot. Usually this alone is not enough to reproduce the bug, so you start examining the code, looking for possible code execution flows that might have been taken by the CPU to trigger the bug.

In other words, we maintainers need to invest the mental power to read the code surrounding the stacktrace in hopes to discover the proper code execution flow which may lead to the bug. All that so that we could reproduce/trigger the bug ourselves, in our happy contained debug environment. Thus:

  • The execution flow of the code must be obvious: you can't understand the algorithm if you can't follow the instructions in the algorithm. Too many misnamed utility methods, too many asynchronous calls with callbacks (especially if they continue the algorithm in a completely different class/actor/observable) seriously hinder the readability.

To find the code execution flow that led to the bug, you usually need two things:

  • A stacktrace, with possibly good error message, to point you at the end of the code execution flow, and
  • The code, obviously.

The better the stacktrace, the stacktrace's message and the code, the faster we can discover the code execution flow. In order to discover the code execution flow faster, the code should have the following properties:

  • Code Readability - it's obvious on the first sight what the code does. By no means I'm implying that the code is the documentation; however to fix a bug, one first needs to read the code and understand it. Badly named variables, too many clever filters in your List-filtering code, and you'll need comments to explain that particular spaghetti.
  • Code Locality - the code doing similar functionality should be co-located: in one class, in one file, in one package. That's how we human beings like things that relate - nicely wrapped in one box.
  • Ability to Navigate - to understand the algorithm one must understand the functions which the algorithm calls. You must be able to Ctrl+click to anything in the code and IDE must navigate to code which implements that thing, be it a function, class, interface, operator, property, anything.

I have drafted a sketch list of things that tend to hinder these properties.

Overzealous protection against copy-paste

Affects: Code Readability

So now you've extracted all repetitive code to utility methods. Congratulations! Now your function calls a function, which calls a function, which calls a function... If those functions are not well-defined or they are misnamed, the code readability will suffer.

Often there are multiple methods which share only a few lines of the code. One usually extracts the moving parts to an abstract class (generally a bad idea, see below) or introduces some builder, with moving parts injected as blocks or Runnables (ugly, but better than using inheritance).

Remember: every rule has an exception and sometimes it's better to copy-paste. Especially in the UI world: either turn part of the UI into a reusable component, or copy-paste mercilessly.

OOP Inheritance

Affects: Code Readability

The main principle of OOP is still awesome: cram related code to a single class, which improves code locality. Hiding stuff into private produces sane autocompletion results and makes your component really usable. Trouble starts when you start using functionality from those classes. You generally have to choose whether to use functionality (that is, call methods) from other class either by reference, or by inheritance.

Composition promotes components: reusable objects with well-defined API that do not leak their internals and do stuff. This is the good approach.

Inheritance promotes adding functionality by extending classes. Peachy, but it's not easy to do it properly. Quoting Josh Bloch: Design and document for inheritance or else prohibit it:

  1. Your protected methods are now part of the API as well
  2. Constructor must not invoke overridable methods. This is because the overrided method in the constructor of super class will always be invoked before the constructor of the sub class. This may cause invocation of an object before that object has been initialised properly.

Ever tried to read a class which extended a deep hierarchy, and methods were magically called out of nowhere? You're effectively combining your class with all of the code from all of the subclasses, and you need to understand those as well. This hurts code locality (since superclasses are located completely elsewhere), and also code navigability (since it may only be clear at runtime what the method will actually do, thanks to polymorphism).

I once had a colleague who blindly followed the newest hip rule in OOP, quoting: "every class must have an interface". There were lots of interfaces in that project. Ctrl+Click would bring you to an interface. Luckily nowadays with Intellij you just press Navigate - Implementations, but it hurted the code navigability quite badly back then.

Dynamically-Typed Languages

Affects: Ability to Navigate

The very foundations of dynamic languages (say, JavaScript, Ruby, Python) are based on duck-typing - if a class has quack() method then it can quack. The problem with duck-typing starts to show once you Ctrl+click on the quack() function call and realize that the IDE has no way of knowing of:

  • which class you are trying to call (since you often do not specify the type of the class)
  • whether the callee class actually has the quack() method or not (since the method_missing() catch-all may be used)

Thus, on every Ctrl+click, the IDE usually presents all classes that define quack() method (unless it can guess the callee class type); and this list may actually not list all possible target code points because of method_missing().

Incorrect Code Grouping

Affects: Code Locality

Sometimes people tend to put all JPA entities into one package, all Controllers into the controller package, all Views into the view package. This causes the code to be grouped by type instead of by the functionality. This is the same fallacy as grouping racing cars by color (not the best parable but it's the best I have ;).

The fix is actually quite easy: all Views, Controllers and JPA entities dealing with the customer should instead be placed into the customer package (unless of course there is a glaring reason to do otherwise, for example when the JPA entity resides in a completely another layer, invoked remotely via REST).

Overuse of Annotations (Annotatiomania)

Affects: Ability to Navigate, Code Readability, Code Locality

An example:

@Transaction
@Method("GET")
@PathElement("time")
@PathElement("date")
@Autowired
@Secure("ROLE_ADMIN")
public void manage(@Qualifier('time')int time) {
...
}

Ctrl-clicking on @Transaction will take you to the Transaction annotation definition which contains no code. To actually see the code, one needs to search for any code touching that annotation in all libraries (and this is actually impossible with JavaEE). And then one usually encounters an uber-complex function dealing with all of the annotation parameters (say, code dealing with Required/RequiresNew/Mandatory/NotSupported/Supports/Never transaction attributes, XA transaction handling, bean/container managed transactions) which is virtually impossible to grok in a sane time span.

The idea behind annotations is noble: to standardize a particular functionality and make it configurable via annotations. Using the convention-over-configuration principle one can often simplify the annotated class so that the intent is immediately clear (say, @RequiresRole("ROLE_ADMIN")). However, often that is not enough, and in the fervous attempt of avoiding code writing, an annotation-based DSL language is born. Usually with morbid results, for example @Secure({@And(@RequiresRole(@Or("ROLE_ADMIN", "ROLE_MANAGEMENT")), @RequiresLoginPlace("ACME_HQ")}). The problem is that annotations do not actually execute anything; the actual implementation handling all aspects of the configuration is thus someplace else, not easily reachable (making the possibility to navigate hard). This can be remedied for example by specifying access verifier class in the annotation; however the code that actually calls the verifier class is still hardly reachable.

However, sometimes this may be acceptable. Say, Retrofit: the library is simple enough so that the functionality is clear; also one rarely needs to actually dig into its core and check how exactly that GET is executed. And since Retrofit forms a simple detained island which does just one thing (as opposed to Spring with all its plugins which tend to permeate all of your code base), the complexity is detained within an acceptable black box.

The interceptor annotations such as @Transactional can be replaced with custom functions with blocks, for example:

db { em.persist(person) }

The db is just a function which starts and commits (or rollbacks) the transaction. It has some 15-20 lines, is easy to understand, and you can just Ctrl+Click on the db function name to navigate directly to the source code. The idea behind the db {} function is described in mode depth in Writing Vaadin Apps In Kotlin part 3. And you can just call this function from anywhere, as opposing of having an injector everywhere (by making all classes managed beans) and injecting @Transactional class which finally can call the database.

Should the db{} function stop serving your needs (no XA or other reason), just fork and write your own, or use XA vendors. It's actually not that hard: the dirty little secret of XA is that it is still not 100% error proof; naive approach may work here quite well.

JPA

Affects: Ability to Navigate

JPA is a tough beast. Its sheer amount of annotations makes you want to run and hide. There is absolutely no way one can understand what's going on behind the scenes by a simple Ctrl+click approach. However, once one follows a good tutorial and learns how to navigate himself around pitfalls such as detached beans, then it does its job and is again an acceptable black box.

Yet, I grew weary of constant surge of exceptions, N+1 selection problems and now I just select exactly what I need with plain SQL selects, using sql2o plus a bit of code to add simple CRUD capabilities in the Vaadin On Kotlin framework.

Loose Coupling

Affects: Ability to Navigate

Loose Coupling of large modules makes sense - it's not easy to understand the modular structure of the app if all of the modules leaks internals like hell. However, it is easy to go all loose-coupling-crazy, stuff everything behind interfaces and thus turning Ctrl+click into searching for implementors of that particular function (and God forbid should there be more than one!). The granularity here really matters. Loose Couple on module level, tightly couple on package level.

Argumenting by loose coupling is often fallacious. Say, "using Rx makes your code loosely coupled". This actually sounds like a good thing, until you realize that you can no longer see the code flow! To rebute this fallacy, just ask:

  1. Do we need loose coupling in this particular place?
  2. Does it outweight the cost of not seeing the code flow anymore? (Usually it doesn't).
  3. Are you just fallaciously promoting your favourite framework?

Remember: Loose coupling directly reduces the ability to navigate and the possibility to read the code flow.

Interceptors / Aspects

Affects: Ability to Navigate

The interceptors/aspects are immensely popular with the Dependency Injection frameworks. However, when overused, this can become a maintenance nightmare. Usually interceptors are employed by the means of annotating class/function, which hurts the ability to navigate, but is still doable - by searching all accessors of that particular annotation one can eventually learn the code that "executes" the annotation (even though this gets harder as the number of annotated components increase). However, interceptors can also be configured (in Spring XML or Guice Module) so that theyapply to certain class types (and subclasses) only, and that makes them virtually undiscoverable for any coder who just joined the project. This directly boosts the coder's frustration and the desire to leave that project, which is not what you want.

One of the solutions may be to use functions with blocks instead, as shown with the db {} example.

Java Stream API

Affects: Code Readability

A simple filtering with Java Stream API turns into this:

list.stream().filter(it -> it.age > 0).collect(Collectors.toList());

The stream() and collect(Collectors) is just a noise, however in Java this noise takes almost half of the entire expression, which decreases readability. Compare that with the following Kotlin expression:

list.filter { it.age > 0 }   // the result is already a list.

Going more stream-crazy allows you to write unreadable code like this:

Stream<Pair> allFactorials = Stream.iterate(
  new Pair(BigInteger.ONE, BigInteger.ONE),
  x -> new Pair(
    x.num.add(BigInteger.ONE),
    x.value.multiply(x.num.add(BigInteger.ONE))));
return allFactorials.filter(
  (x) -> x.num.equals(num)).findAny().get().value;

Please read more at This Is Not Functional Programming. Streams are to be used cautiously: Java's nature is not a functional one, and using Java with functional approach is going to produce weird code with lots of syntactic sugar, which will make little sense to traditional Java programmers.

To avoid the noise introduced by Java you can consider switching to Kotlin.

Java Optional API

Affects: Code Readability

Optional is the Java's way to deal with nulls. Unfortunately Optional introduces methods which tend to be used instead of the built-in if statements. Consider this code:

optionalString=Optional.ofNullable(optionalTest.getNullString());
optionalString.flatMap(s->something).ifPresent(s->{System.out.println(s.toString());}).orElseThrow(()->new RuntimeException("something"));

Using the traditional approach of ifs and null-checks would have worked better here.

Optional is also capable of breaking of the Bean API. Consider the following code:

public void setFoo(String foo) {}
public Optional<String> getFoo() {}

This is actually not a property since the type for setter and getter differs. This also breaks the Kotlin support for propertyising Java beans. The code could be fixed by changing the setter to setFoo(Optional<String> foo) but that makes it really annoying to call the setFoo method.

Instead, it is better to use Intellij's @NotNull annotation and traditional language statements. The resulting code tends to be way more readable than any Optional black magic.

Spring, JavaEE, Dependency Injection

Affects: Ability to Navigate, Code Readability, Code Locality

Spring was founded as an alternative for J2EE, which in the old days contained a lot of XMLs. At that time it was lean; nowadays it has tons of modules, with varying quality of the documentation. It seems that Spring permeates everything and uses all of the above methods:

  • In a lots of projects, the wiring granularity is too high. Instead of wiring modules, it often wires classes, often with synthetic interfaces in front of those. This is basically Loose Coupling on a way too granular level, which makes the navigation in such code harder.
  • Uses interceptors/annotations heavily. Spring Data, Spring Security for example. Spring Security has became so huge that coders are avoiding it on purpose.
  • Uses clever tricks to employ interceptors. To employ interceptors to a class, Spring uses the CGLIB library to create a dynamic class which extends the original one, overrides all methods and invokes interceptor chain. This has the unfortunate side-effect of having lots of $$$PROXY fields with null values which clutter the state of the original class.

JavaEE suffers from the very same problems, and adds the following issues on top:

  • It is impossible to see the actual implementation of, say, @Transactional, since it's implemented somewhere in the application server, which may not even be OSS. And even if it was possible, the code is highly complex and hard to read.
  • If JavaEE can't employ annotation, it simply will ignore it. For example, calling @Asynchronous method on the same bean instance will silently result in a synchronous call. This directly violates the main principle since the program silently does something else than it should, from the look of the code. To actually call the method asynchronously, the class needs to inject itself and call the method on that.

The Dependency Injection paradigm is highly invasive. For example, the need of injecting classes into Vaadin (or Swing, JavaFX) components: since all DI frameworks usually tend to hide Injector from the programmer, the programmer usually makes every Vaadin component a managed bean, to have depending services injected. This makes it harder to use java-debug class-reloading techniques.

I've seen people using Spring only because of Spring Boot, since it is a pain in the ass to launch a war project in Eclipse. Let me rephrase: one's code base hurts just because the tooling of his choice sucks.

Overuse of async: Reactive, EventBus, AKKA

Affects: Code Locality, Ability to Navigate

Reactive, Rx, React or whatever the asynchronous programming is called today. On larger granularity, and with proper task, it makes total sense to employ AKKA Actors: when they are big enough in order for them to form a grokkable box of synchronous functionality in which you can navigate. Also, in large loads, having too many thread being blocked will cause their stacks to eat the memory, so async is always the way to go, right? It depends.

It is true that it is extremely handy to have only a single thread in node.js, or a single thread in AKKA actor consuming messages, as opposed to traditional multi-threaded approach. With a single thread, you don't need to worry yourself with guarding your shared state with locks. And with advanced techniques like promises and/or coroutines, neither code locality nor ability to navigate suffers.

Shit tends to hit the fan when you have a hammer labelled Rx and every problem is a nail. Then, usually Observable gets slammed on every button listener, splitting the previously readable synchronous listener method into chunks of three-line asynchronous objects. There is no way to navigate there - this is like a too granular Dependency Injection all over again, since the code which configures (creates a pipelines of those asynchronous small blocks) is usually completely elsewhere than the code itself. This horribly affects the code locality.

Even worse when you have lots of actors with no promises/coroutines to handle request/response type of messages. If all you have is just an onMessage() method, then it's usually very hard or impossible to figure out who sent the message and thus who the caller is, and thus the ability to navigate suffers. And even more worse when the actor needs to send and receive messages in certain order. Then you need to mark down in the actor state which message you already received and which you still need. You are effectively creating a defensive state machine. State machines are hard to maintain, since by adding more state raises the possible code execution flows exponentionally. This price is rarely worth more than any dubious benefits the async approach may have.

Debugging suffers with async as well - it is no longer possible to debug and check the stacktrace for the information who called you, since the caller is usually a background message-processing thread. To actually get the caller, you need to track the code which created the message, as mentioned above.

The motto of EventBus - fire [the event] and forget - can be read as I have no idea what is going on when I fire this event since it's nearly impossible in design time to discover all event receivers who gets notified. This hurts the ability to navigate.

Java 8 Default Methods on Interfaces

Affects: Code Locality

Everything is fine when the default methods are used purely as utility methods (or in place of extension methods since Java is lacking those). The hell breaks loose if the interfaces are used as traits, adding completely new functionality, demanding to store the state as in the following example:

interface Bark {
    public abstract int getBarkedCount();
    public abstract int increaseBarkedCount();
    default public String bark() {
        increaseBarkedCount();
        return "barked " + getBarkedCount() + " times";
    }
}

Of course this example is simple, silly and self-explanatory. Yet, imagine having 4-5 of such interfaces implemented on an object, each bringing its tiny little functionality inside the object, but every piece of functionality stored in a different file. The code locality suffers: it can no longer be seen what the object is responsible for, what's the actual state and what are the state mutation paths. The object becomes a God object with a lots of responsibilities.

Missing Comments

Affects: Code Readability

Quoting Uncle Bob's Clean Code book, chapter 4:

Comments are, at best, a necessary evil. If our programming languages were expressive enough [...], we would not need comments very much. The proper use of comments is to compensate for our failure to express ourselves in the code.

That's totally wrong, stupid, and very dangerous:

  1. People who take that literally will end up with having no comments in their code, and they will be proud of that. I can't even begin to describe how stupid that is.
  2. Uncle Bob actually contradicts himself - at first he says that all comments are evil, and then he lists examples of good comments: legal comments (!!! yeah, truly the most important type of comments. Uncle Bob, certainly you do care about code clarity, right?), informative comments, explanation of intent...
  3. The "expressive language" myth is easy to debunk: there is no such language. Scala tried and failed to produce not even code with intents, but even readable code. Computers don't execute intents, they execute code and they don't care about intents. Computer code is not about what we want the computer to do, it is about what the computer will do, and those are two different things. Thus, we need comments to explain our intents.

In short, having no comments because of fear that the comments may get obsolete, is just plain stupid.

Scala

Affects: Code Readability

There are languages which say what they do in English, and then there's Scala:

 
5 months ago

You have your superdevmode development environment up and running. All is peachy and world is unicorns until you figure out that some pesky bug is only reproducible on a cell phone. Bam. What now?

No worries! The totally awesome thing about PC Chrome is how easy it is to access the phone's Chrome browser log, modify DOM, everything. All this from the comfort of your PC. Just follow this tutorial and prepare for a major wow effect: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/ . Simply by clicking that Inspect button you will be able to use the full power of Chrome Dev Tools on your PC, of a page displayed and running in Android's Chrome.

Usually both the PC and Android are connected to the same wifi, and thus Android will see the PC. I'm going to assume here that your PC's IP is 192.168.100.17. Naturally you will type in http://192.168.100.17:8080?superdevmode into Android's Chrome and naturally it won't work.

The usual approach is to add tons of configuration options as stated below. TL;DR: skip them and use the port forwarding solution below which is way easier and less error-prone.

The old and traditional solution which you'll want to avoid unless port forwarding is not an option for you for some reason

We need to configure stuff first.

  1. First we need to open up the codeserver so that it accepts connections from all over the world, not just from localhost. Open your mvn vaadin:run-codeserver launch configuration in intellij, and set Command line to vaadin:run-codeserver -Dgwt.bindAddress=0.0.0.0
  2. To force the Android Chrome browser to connect to the proper codeserver one needs to set it in the URL. Just make the Android Chrome Browser to open http://192.168.100.17:8080?superdevmode=192.168.100.17
  3. To avoid this pesky message "Ignoring non-whitelisted Dev Mode URL:" in your Android's Chrome (some security precaution introduced in GWT 2.6) you need to bootstrap from a slightly modified widgetset.gwt.xml. Just follow http://stackoverflow.com/questions/18330001/super-dev-mode-in-gwt and add the following into your widgetset.gwt.xml and recompile, so that you will bootstrap with proper settings:
    <set-configuration-property name="devModeUrlWhitelistRegexp" value=".*" />
    

Now what to do if you don't have your own widgetset but instead you are just using the precompiled one from vaadin-client-compiled.jar? Obviously you will bootstrap off the default unmodified DefaultWidgetSet.gwt.xml from vaadin-client-compiled.jar. You could do mvn clean install of modified Framework client/src/main/resources/com/vaadin/DefaultWidgetSet.gwt.xml but we can be smarter and use port forwarding.

Port Forwarding

Instead of twiddling with countless configuration options we will pretend that your phone is the one who is actually running the server. By doing that we can just type in http://localhost:8080?superdevmode into Android's browser and thus bypass those pesky security precautions. This can be done by somehow listening on TCP ports 8080 and 9876 on your phone; when someone connects, just send all data to the PC. This technique is called port forwarding.

Make sure you have Android SDK installed. You can download that for free here: https://developer.android.com/studio/index.html - you can either download the full-blown Android Studio which comes with the SDK itself, or just scroll down to the end of the page and install the sdk-tools, the choice is yours. We will only need the adb binary anyway.

Now open up your console and type in the following:

$ adb reverse tcp:9876 tcp:9876
$ adb reverse tcp:8080 tcp:8080
$ adb reverse --list
(reverse) tcp:9876 tcp:9876
(reverse) tcp:8080 tcp:8080

If adb complains that error: no devices/emulators found just close your PC's Chrome, so that it will close its connections to Android and will thus allow adb to connect.

Now fire up Chrome, Remote, and just type http://localhost:8080?superdevmode into your Android Chrome and you should be good to go.

FAQ

Q: The widgetset compiles but my changes aren't applied

A: Simply use the port forwarding solution. Else make sure there is no "Ignoring non-whitelisted Dev Mode URL:" message in the browser's console. If there is, you will need to bootstrap off a modified widgetset.gwt.xml.

Q: The widgetset recompilation fails

A: Simply use the port forwarding solution. Else make sure the codeserver listens on all interfaces (netstat -tnlp|grep 9876 will give you :::9876 instead of 127.0.0.1:9876). Also make sure you're using ?superdevmode=192.168.100.17 in the Android Chrome's URL.

Q: adb list won't show my phone and/or complains with error: no devices/emulators found

A: Make sure that your PC's Chrome is not connected to Android. Close all Chrome Remote windows; close all the "Remote Devices" tabs in PC Chrome. Or simply close Chrome while we configure port forwarding.

 
5 months ago

When trying to fix some browser-side issue in Vaadin built-in components, it is often useful to modify those component sources while your app is running. This way, you can modify e.g. VButton.java, refresh your browser with F5 and immediately see the changes done in Vaadin Button. This blogpost describes how to configure Intellij to do just that.

We will need two things:

  • A standard Java Vaadin WAR project which employs the component we are going to modify, e.g. com.vaadin.ui.Button. You can use your own project; if you don't have one, for the purpose of this article you can easily generate one at https://vaadin.com/maven
  • The Vaadin Framework sources checked out from git. I'll guide you later on.

First, start by running your Vaadin-based WAR application from your IDE as you usually do. I assume here that you use only the default widgetset, with no added widgets; I need to write another blogpost on how to debug your custom widgetset.

Now that your app is up and running and accessible via the browser at, say, http://localhost:8080, we are going to employ GWT superdevmode. Generally, the idea here is that once a special Vaadin switch is activated (?superdevmode added to your url), the browser will be configured by the Vaadin Framework to serve widgetset javascript not from your project's WAR, but instead from a GWT so-called codeserver which we will launch in a minute. The codeserver does two things:

  • when you press F5 in your Chrome, the codeserver will perform a hot javascript recompilation of Vaadin client-side widgets modified by you, and it will feed the compiled javascript to your Chrome.
  • the codeserver will also provide so-called sourcesets for Chrome browser so that you will see an actual original Java sources in Chrome and you will be able to debug them from Chrome.

Let us start by grabbing Vaadin sources:

$ git clone git@github.com:vaadin/framework.git

Make sure that you checkout appropriate branch (e.g. 8.0 if you use Vaadin 8.0.x, 7.7 if you use Vaadin 7.7.x etc), then compile:

$ mvn clean install -DskipTests

Then just open the main framework/pom.xml in Intellij. There will be compilation errors regarding import elemental.json.JsonObject missing, you can safely ignore those.

Launching the codeserver properly is tricky and produces lots of errors when not done right. To put it bluntly, codeserver is a bitch, prepare for lots of cursing and wasted time, you've been warned. The easiest option is to use maven vaadin plugin. Just open the Maven tool window in the Intellij in which you have the framework sources opened, go into vaadin-client-compiled / Plugins / vaadin / vaadin:run-codeserver, right-click and select Create "vaadin-client-compiled..." launch configuration. The most important part is the Resolve Workspace artifacts:

  • When it is unchecked, Maven will use vaadin-client.jar from ~/.m2/repository, meaning that you will need to run mvn clean install inside the client project every time you modify Vaadin GWT sources. This is definitely suboptimal and we can do better.
  • When it is checked, Maven will prefer client sources over jars from ~/.m2/repository. However, activating this mode and Debugging this launch configuration will sometimes fail to compile the DefaultWidgetSet with some ridiculous error message. If this happens, just read below for a workaround.

Workaround for vaadin:run-codeserver not starting: So, what now? Simple - just attach the sources as resources :-) Uncheck the Resolve Workspace artifacts, save the launch configuration. Then, open the client-compiled/pom.xml file and add the following snippet right below the <build> element:

    <resources>
        <resource>
            <directory>../client/src/main/java</directory>
        </resource>
    </resources>

Now it will be possible to launch the vaadin:run-codeserver task, and with it, the codeserver. The codeserver should eventually print something like this to the console:

[INFO] --- vaadin-maven-plugin:8.1-SNAPSHOT:run-codeserver (default-cli) @ vaadin-client-compiled ---
[INFO] Turning off precompile in incremental mode.
[INFO] Super Dev Mode starting up
[INFO]    workDir: /tmp/gwt-codeserver-1604961084994240944.tmp
[INFO]    [WARN] Deactivated PrecompressLinker
[ERROR] SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
[ERROR] SLF4J: Defaulting to no-operation (NOP) logger implementation
[ERROR] SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO]    Loading Java files in com.vaadin.DefaultWidgetSet.
[INFO]    Module setup completed in 14374 ms
[INFO] 
[INFO] The code server is ready at http://127.0.0.1:9876/

Now that the codeserver is running, let us use it. In your Chrome, modify the URL to http://localhost:8080?superdevmode (or http://localhost:8080?superdevmode#!someview if you are using Navigator). The browser should say that it is recompiling the widgetset, and after a while, your app should appear as usual. To prove that the app is indeed using the codeserver, we will modify the VButton.java a bit.

Open the VButton.java in Intellij where the codeserver is running, and head to the constructor. At line 118, at the end of the constructor, just add the following line:

addStyleName("woot-my-style");

Save and hit recompile CTRL+F9. There may be compilation errors regarding import elemental.json.JsonObject missing, you can safely ignore those - the VButton.java will be hot-redeployed to the codeserver anyway.

Now, head to the browser, press F5, then Ctrl+Shift+C and click any Vaadin button. The appropriate div should now have the woot-my-style class. If not, kill the codeserver and make sure you are using the <resources> workaround above, with Resolve Workspace artifacts unchecked.

This concludes the hot-compilation part. Now for the debugging part. Press F12 in Chrome and head to the Sources tab. Now patiently unpack com.vaadin.DefaultWidgetSet / 127.0.0.1:9876 / sourcemaps/com.vaadin.DefaultWidgetSet / com / vaadin (at this point I start to wonder whether coping with all this is really worthwile, now that we have Kotlin2JS) / client / ui / VButton.java. You see java sources in a browser. Cool. Now place a breakpoint at line 118 where the addStyleName() resides, and press F5. Chrome should now stop at that line. You can use leftmost debugger buttons to fiddle with the execution flow.

FAQ

Q: The codeserver fails to start with

[INFO] [ERROR] cannot start web server
[INFO] java.net.BindException: Address already in use

A: CodeServer loves to stay running even when killed by Intellij. Just do netstat -tnlp|grep 9876 and then kill the offending java CodeServer process.

Q: The codeserver does not pick up the changes I made

A: Make sure you are launching the codeserver in Debug mode. Then, make sure you saved the java file and hit CTRL+F9. Also make sure you are using the <resources> workaround above, with Resolve Workspace artifacts unchecked.

Q: The codeserver fails to compile widgetset because of some ridiculous compilation error

Make sure you are using the <resources> workaround above, with Resolve Workspace artifacts unchecked.

 
6 months ago

When doing mobile development with Vaadin, you often develop the app on your dev machine and view the page on a tablet or a phone. Yet, entering your dev machine IP into the phone browser may be tedious and error-prone. There is a way though, to enter an URL to your phone. Via a camera, as a QR Code.

Imagine having a special PopupView in your menu, which would upon clicking reveal the QR code to your machine :-)

With Vaadin On Kotlin this is easy. Just use the QRCode Vaadin Component and add the following code:

val hostIPAddress: String? get() {
    val iface = NetworkInterface.getNetworkInterfaces().toList().filter { it.isUp && !it.isLoopback && !it.isVirtual }.firstOrNull() ?: return null
    val address = iface.inetAddresses.toList().filterIsInstance<Inet4Address>().firstOrNull() ?: return null
    return address.hostAddress
}

fun HasComponents.qrcode(value: String, block: QRCode.()->Unit = {}) = init(QRCode()) {
    this.value = value
    block()
}

Then, in your UI somewhere:

if (hostIPAddress != null) {
    popupView("QR Code") {
        verticalLayout {
            val url = "http://${hostIPAddress}:8080/"
            label(url)
            qrcode(url) { w = 300.px; h = 300.px }
        }
    }
}

And voila! Just launch the Barcode Scanner app and point your tablet or your cellphone towards your screen.

 
7 months ago

Let's discuss the most useful cases for the extension methods. First use-case: extension methods allow to apply themselves only selectively. For example, the following method only applies to a list of Person:

fun Iterable<Person>.averageAge(): Double = map { it.age }.filterNotNull().average()

No longer it is necessary to create classes which only perform summarization functionality over a collection of objects - you can now attach that functionality directly to a Iterable or a Collection.

Second use-case is even more interesting. Let's create a Session object as follows:

object Session {
    operator fun get(key: String): Any? = VaadinSession.getCurrent().getAttribute(key)
    operator fun set(key: String, value: Any?) = VaadinSession.getCurrent().setAttribute(key, value)
}

This will allow to store stuff into the Session as follows: Session["key"] = value. But this is not the interesting part. The interesting part comes here:

fun login(person: Person) {
    Session["user"] = person
}
fun logout() {
    Session["user"] = null
}
val Session.loggedInUser: Person? get()= Session["user"] as Person?

Yes, yes, login/logout, standard stuff, what's your point? The main point is that we extended the Session with the loggedInUser property. And by "we" I mean that anyone can do this - another class, another jar file, another module. Consider this: lots of jars, lots of modules contributing stuff to the central Session class. You can use that stuff, as long as those jars are on your classpath. This is not about pluggability, this is about modularity and about discoverability of services. Your IDE will auto-discover all services and will provide you a neat list in the form of auto-completion on the Session object. And in some applications, this approach may even replace simple injections - that is, injections with one implementation and with no interceptors. But - don't we strive for all injections to be simple?

Interesting times we live in ;) And that's all folks, thank you for reading these ramblings ;) If you wish to see these ideas in practice, please check out the following Github project: https://github.com/mvysny/vaadin-on-kotlin - it includes the production-ready db{} function, Grid integration for rendering of your DB tables in your page and more. Check out the sample project as well.

 
7 months ago

Now if there was some way to get rid of that pesky em -> which needs to be written every time one calls the db {} function. If only there was a way we could tell a block to "know" some variables implicitly... Maybe we could throw those "variables" into a class and tell the block to run as some kind of an extension method in that class? That could work - extension methods have direct access to the receiver object methods and variables. Remember our findAll() method?

fun <T: Any> EntityManager.findAll(clazz: KClass<T>): List<T> = createQuery("select a from ${clazz.java.simpleName} a", clazz.java).resultList

The findAll() extension method is apparently able to access the createQuery() method which belongs to the EntityManager. So. How about we create a object which has em as its field? Right on:

class PersistenceContext(val em: EntityManager)

Now we modify the db() method as follows:

fun <R> db(block: PersistenceContext.() -> R): R {
    val em = emf.createEntityManager()
    try {
        em.transaction.begin()
        val result = PersistenceContext(em).block()
        em.transaction.commit()
        return result
    } catch (t: Throwable) {
        try {
            em.transaction.rollback()
        } catch (t2: Throwable) {
            t2.printStackTrace()
        }
        throw t
    } finally {
        em.close()
    }
}

The block definition changed from (EntityManager)->R (that is, take EntityManager as its parameter and return R) into PersistenceContext.()->R, that is, pretend that the block is some weird kind of extension method of PersistenceContext. And we will call it in this new fashion:

PersistenceContext(em).block()

After these modifications you'll have compiler errors - this is because the db {} block now has no parameters. Just fix them by removing the em -> stanza from your db {} method calls.

With this approach, we can toss in some additional variables which may come handy. For example, sometimes it is handy to circumvent EntityManager and go directly into JDBC. No problem:

class PersistenceContext(val em: EntityManager) {
    val session: SessionImpl get() = em.unwrap(SessionImpl::class.java)
    val connection: Connection get() = session.connection()
}

From now on, you can use connection in your db {} calls. Just like that. Awesome, isn't it?

Now, I need you to play with this thing a bit, so that it has the time to soak in and become native to you. Because in the next lines we will combine everything you have learned, into a mind-blowing big ball which may get too overwhelming. Just tell me when you're ready :-)

Ready? Now I want you to read this article and understand everything from it: https://kotlinlang.org/docs/reference/type-safe-builders.html. Don't worry - once you grok that article, that's it - you just learned everything I need you to know, and further text will be completely straightforward.

So, now you grok this DSL thingy. Cool, huh? You can basically model a tree structure type-safe with Kotlin. Hey, Vaadin components are arranged in a kinda tree fashion! You know, VerticalLayouts containing HorizontalLayouts containing other components... Let's build a Vaadin DSL!

Let's create a Kotlin file named VaadinDSL and let's start by introducing a builder method for VerticalLayout:

fun HasComponents.verticalLayout(init: VerticalLayout.()->Unit): VerticalLayout {
    val vl = VerticalLayout()
    add(vl)
    vl.init()
    return vl
}

I chose to add this extension method into HasComponents, so that both ComponentContainers+Layouts and SingleComponentContainers are supported. Since VerticalLayout is also HasComponents, you can now nest vertical layouts. But there is a problem: HasComponents has no "add" method! Easily fixable though:

fun HasComponents.add(component: Component) = when (this) {
    is ComponentContainer -> this.addComponent(component)
    is SingleComponentContainer -> this.content = component
    else -> throw IllegalArgumentException("Don't know how to add items to $this")
}

Let's introduce a few more builders for Button, TextField and PersonEditor, so that we can rewrite our MyUI, builder-style!

fun HasComponents.textField(caption: String? = null, init: TextField.()->Unit = {}): TextField {
    val component = TextField(caption)
    add(component)
    component.init()
    return component
}

fun HasComponents.button(caption: String, init: Button.()->Unit = {}): Button {
    val component = Button(caption)
    add(component)
    component.init()
    return component
}

fun HasComponents.personEditor(init: PersonEditor.()->Unit = {}): PersonEditor {
    val component = PersonEditor()
    add(component)
    component.init()
    return component
}

(There is some code pattern, repeating again and again. I'll leave the refactoring to you ;). Note the default values for the init parameters. This way, the block is not required and we can leave that out if we wish so. This allows for simple textField("name") instead of having to write textField("name") {}. And thus, we can rewrite the init() method as follows:

val persons = Person.findAll()

verticalLayout {
    setMargin(true); isSpacing = true
    val layout = this
    val name = textField(persons.joinToString())
    button("Click Me Kotlin") {
        addClickListener { layout.add(Label("Thanks ${name.value}, it works!")) }
    }
    personEditor {
        edit(persons.last())
    }
}

The structure of the Vaadin component graph is now more visible than in the previous "flat" code. Please play with the code a bit. Next, yet another application of the extension methods.

 
7 months ago

I'll get to the forms right away. But first, I want to talk extension methods. They are immensely helpful in adding functionality to objects. Note that Kotlin is not a dynamic language - the methods will not really be added to target classes, it is just a syntactic sugar. Quite delicious, though. So, EntityManager misses the findAll method - let's fix that. Open the DB.kt file and add this to the end:

fun <T: Any> EntityManager.findAll(clazz: KClass<T>): List<T> = createQuery("select a from ${clazz.java.simpleName} a", clazz.java).resultList

Read more here: https://kotlinlang.org/docs/reference/extensions.html. Basically, what we just did is that we "kinda added" a findAll method to the EntityManager, which invokes the createQuery() method of the EntityManager itself and runs given query. From Java's perspective we have created a static method findAll(EntityManager $receiver, Class<T> clazz): List<T> on a class named DBKt - this is what's actually produced by the Kotlin compiler. Let's use it and let's implement findAll() which finds all Persons. I personally believe that such code belongs to the class dealing with personnel, as per OOP imperative "code shall be with the data", don't you agree? So, let's create a finder right on the Person class:

@field:Column(nullable = false)
var age: Int? = null
) {
companion object {
    fun findAll(): List<Person> = db { em -> em.findAll(Person::class) }
}
}

Companion object is Kotlin's way of doing Java static stuff. Seems more complicated than static methods, until you realize that the companion object is also an object, and as such it may inherit from other objects, implement an interface, so it is immensely more powerful. Read more here: https://kotlinlang.org/docs/reference/object-declarations.html. Let's head back to MyUI and modify the init() method:

db { em -> em.persist(Person(name = "Zaphod", surname = "Beeblebrox", age = 42)) }
val persons = Person.findAll().joinToString()

There. More easy to read, and one can just intuitively head to the Person class and auto-complete to find this useful function. We'll leave extension methods for now, but we'll return to them as they are immensely useful.

Tip: Now maybe is the time to purchase IDEA Ultimate. The Ultimate edition has a built-in database browser which also integrates with Java/Kotlin editors and provides auto-completion and validation of your database queries. Let's browse the embedded H2 database by opening the upper-right Database Tool Window, clicking the green + button and import from sources. IDEA auto-discovers the persistence.xml, extracts the connection string from that so you only need to provide the username "sa" and password "sa". If the Test Connection button is greyed out, see below - the H2 driver may be missing. Just click the Download link, IDEA will download the driver and you will be able to add the database. Then, expand the database, click More Schemas - PUBLIC, select the PERSON table and press F4 - you will see the table contents. This kind of connection will work because H2 is in mixed mode: http://www.h2database.com/html/features.html#auto_mixed_mode

Now, back to the forms. We will employ Vaadin's BeanFieldGroup to edit the bean. Let's create a Kotlin class PersonEditor:

package org.test.myvaadin

import com.vaadin.data.fieldgroup.BeanFieldGroup
import com.vaadin.data.util.converter.StringToIntegerConverter
import com.vaadin.ui.Button
import com.vaadin.ui.FormLayout
import com.vaadin.ui.TextField

class PersonEditor : FormLayout() {
    private val name = TextField()
    private val surname = TextField()
    private val age = TextField()
    private val fieldGroup = BeanFieldGroup(Person::class.java)
    private val save = Button("Save")

    init {
        save.addClickListener {
            fieldGroup.commit()
            db { em -> em.merge(fieldGroup.itemDataSource.bean) }
        }
        age.setConverter(StringToIntegerConverter())
        fieldGroup.bind(name, "name")
        fieldGroup.bind(surname, "surname")
        fieldGroup.bind(age, "age")
        addComponents(name, surname, age, save)
    }

    fun edit(person: Person) {
        fieldGroup.setItemDataSource(person)
    }
}

Be sure to study the BeanFieldGroup javadoc how this class works and how it binds properties (e.g. "name" is really the name field in the Person class) to Vaadin Fields. To use this class, modify MyUI.init() as follows:

override fun init(vaadinRequest: VaadinRequest) {
    db { em -> em.persist(Person(name = "Zaphod", surname = "Beeblebrox", age = 42)) }
    val persons = Person.findAll()

    val layout = VerticalLayout()

    val name = TextField()
    name.caption = persons.joinToString()

    val button = Button("Click Me")
    button.addClickListener { e ->
        layout.addComponent(Label("Thanks " + name.value
                + ", it works!"))
    }

    layout.addComponents(name, button)
    layout.setMargin(true)
    layout.isSpacing = true

    val personEditor = PersonEditor()
    personEditor.edit(persons.last())
    layout.addComponent(personEditor)

    content = layout
}

This will edit the last person in the list. Feel free to play with the editor a bit, and check the database in the Database explorer, to see the last person being modified by your changes. But what about validations? Try clearing the age field and press Save. What happens is that Vaadin happily stores null into Person.age which is supposedly non-null, and thus Hibernate will complain with an exception.

To fix this, we will employ data validations, or JSR-303. Head to pom.xml and add the following dependency:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>5.3.4.Final</version>
</dependency>

We'll add the validation annotations to the Person class as follows:

package org.test.myvaadin

import org.hibernate.validator.constraints.Range
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size

@Entity
data class Person(
    @field:Id
    @field:GeneratedValue
    @field:NotNull
    var id: Long? = null,

    @field:Column(nullable = false, length = 100)
    @field:NotNull
    @field:Size(min = 2, max = 100)
    var name: String? = null,

    @field:Column(nullable = false, length = 100)
    @field:NotNull
    @field:Size(min = 2, max = 100)
    var surname: String? = null,

    @field:Column(nullable = false)
    @field:NotNull
    @field:Range(min = 15, max = 90)
    var age: Int? = null
) {
    companion object {
        fun findAll(): List<Person> = db { em -> em.findAll(Person::class) }
    }
}

The BeanFieldGroup will pick the annotations up automatically and will add appropriate validators to the Fields themselves. To get rid of the horrible stack trace hovering over the Save button, just modify the click listener as follows:

save.addClickListener {
    save.componentError = null
    try {
        fieldGroup.commit()
        db { em -> em.merge(fieldGroup.itemDataSource.bean) }
    } catch (ex: FieldGroup.CommitException) {
        save.componentError = UserError("There are invalid fields in the form")
    }
}

Again, please feel free to play with the code and to study the BeanFieldGroup. Up next, juicy stuff coming. We'll learn how to build the UI properly.

 
7 months ago

Let's add some database to our hello-world. I'll use the pure-Java embedded database called H2 (http://www.h2database.com) which will run as a part of our application, so there is no need for you to install any database engine. Open the pom.xml file and add the following lines at the end of the dependencies element:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.2.6.Final</version>
</dependency>
<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <version>1.4.193</version>
</dependency>

Tip: You can add any dependency on any jar hosted in Maven central this way. Just head to the artifactId element and press Ctrl+Space, to offer the artifacts as you type. To auto-complete from the maven repo, one needs to index it first though, so open File / Settings in IDEA, then Build, Execution, Deployment / Build Tools / Maven / Repositories, select the https://repo1.maven.org/maven2 repo and click update. The update will take a while.

What we just did is that we added two Java libraries:

  • The Hibernate library, which maps Java (or Kotlin) objects to rows in a standard relational database (or RDBMS since Java people love acronyms ;)
  • The H2 database implementation

Now, let's configure Hibernate to use H2. Create the following file: src/main/resources/META-INF/persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="h2" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
            <property name="hibernate.connection.driver_class" value="org.h2.Driver" />
            <property name="hibernate.connection.url" value="jdbc:h2:~/temp/h2/myvaadinapp;AUTO_SERVER=TRUE" />
            <property name="hibernate.connection.user" value="sa" />
            <property name="hibernate.connection.password" value="sa" />
            <!-- <property name="hibernate.show_sql" value="true"/> -->
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>

Tip: to force Intellij to show the currently edited class in the Project tree view, click on the little cog-wheel located in the header of the Project Tool window and check Autoscroll from source.

Now right-click the org.test.myvaadin package in the Project Tool Window and select New / Kotlin File/class. Type in DB and paste the following contents:

package org.test.myvaadin

import javax.persistence.EntityManager
import javax.persistence.Persistence

private val emf = Persistence.createEntityManagerFactory("h2")

fun <R> db(block: (EntityManager) -> R): R {
    val em = emf.createEntityManager()
    try {
        em.transaction.begin()
        val result = block(em)
        em.transaction.commit()
        return result
    } catch (t: Throwable) {
        try {
            em.transaction.rollback()
        } catch (t2: Throwable) {
            t2.printStackTrace()
        }
        throw t
    } finally {
        em.close()
    }
}

First, we have created an entity manager factory, which produces entity managers which look after the JPA objects and map them to the database. Next, we defined a very simple db function which runs a block in a transaction. Note that this function is not present in any class and is thus "global" - this seems like an anti-pattern but at some places this is immensely helpful. More on these blocks or lambdas here: https://kotlinlang.org/docs/reference/lambdas.html. Now that we have the necessary machinery in place, let's create some tables. Let's define a person - create new Kotlin class Person and paste in the following code:

package org.test.myvaadin

import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id

@Entity
data class Person(
    @field:Id
    @field:GeneratedValue
    var id: Long? = null,

    @field:Column(nullable = false, length = 100)
    var name: String? = null,

    @field:Column(nullable = false, length = 100)
    var surname: String? = null,

    @field:Column(nullable = false)
    var age: Int? = null
)

This is a standard JPA so-called entity - an object mapped to a table row. See here how exactly that is done: https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html. Let's now use all the pieces. Open the MyUI class and insert the following code right at the beginning of the init method:

val persons = db { em ->
    em.persist(Person(name = "Zaphod", surname = "Beeblebrox", age = 42))
    em.createQuery("select p from Person p").resultList.joinToString()
}

So, we run the db function which starts the database transaction and gives us the Entity Manager which is the central point for storing stuff into the database. We have created a new person and stored it into the database; then we queried all personnel, returned it from the block and stored into the persons variable. Let's show the variable, in a bit of a stupid way, but nevertheless: just change the code in the MyUI.init() function appropriately:

val name = TextField()
name.caption = persons

Again, please play with the code a bit. The db function has many shortcomings - it does not cache/reuse Entity Managers, it does not cache JDBC Connections, it can't handle nested calls and will create new transactions. No worries - this is just for demo purposes. Later on we will use a real, production-ready stuff. Stay tuned. In the next article we will show how to create forms which will edit our Personnel.

 
7 months ago

Kotlin provides some very interesting language features which are immensely helpful when writing Vaadin apps. Let us start from scratch, building necessary functionality as we progress. The result of this exercise will be a Kotlin-based simple web app, built with Gradle, using Hibernate+JPA to store entities into the database. I will not use Spring nor JavaEE here - the whole thing will run in a pure Servlet environment like Tomcat or Jetty. The complete exercise may take some 60 minutes. I will be using Intellij IDEA Community which you can download for free here: https://www.jetbrains.com/idea/download. When installing, just press the "Skip remaining" button to install Intellij with the default settings.

Originally I intended to write the tutorial using Gradle, but there were bugs in the Gradle Vaadin Plugin which would disallow the app to launch without using IntelliJ Ultimate. Therefore I have chosen Maven with more stable support for tooling.

Let's start by creating a Maven-based Java Vaadin project by following this tutorial: https://vaadin.com/maven (I am using the "org.test.myvaadin" groupId and "vaadin-app" as artifactId throughout this tutorial). Just install Maven 3, follow the steps in the Vaadin tutorial and you're good to go. After you have run the project from the command-line, just fire up IDEA, open the pom.xml file with File / Open; then select Open as Project.

To run the project in IDEA, click on the bottom-left touchpad-like button in the lower-left corner, then click Maven Projects in the upper-right corner. Unwrap the tree: vaadin-app / Plugins / jetty, right-click jetty:run and select Run (or Debug). Then, point your browser to http://localhost:8080/.

Now it may be a good idea to start versioning, so that you can play with the project safely and just revert the changes, should things go banana. Just run this in your command-line, inside the project directory (vaadin-app):

$ git init .

Create a .gitignore with the following contents:

.idea
target
styles.css
*.iml
$ git add .
$ git commit -m "Initial import"

Intellij will detect a git repo, just click "Add Root" in the popup dialog.

Finally, let's Kotlinify the project. Open the MyUI class (by pressing Ctrl+N) and press Ctrl+Alt+Shift+K - this will automatically convert the Java class to Kotlin class. Intellij will show "Kotlin not configured" popup - click "Kotlin" (not Kotlin-Javascript), then just press OK - the pom.xml will be modified automatically.

Tip: to see the cheat-sheet with the keyboard shortcuts in IDEA, just open the Help / Keymap reference menu.

Now, head back to the MyUI class and change the following line: val button = Button("Click Me Kotlin"). Now, when you run the project using the jetty:run as before (or just press Shift+F10 since the Maven launcher for this task has been created, just see the upper-right corner in the IDEA window; this way you can also launch the project in debug mode), Kotlin should auto-compile the class and the page saying "Click Me Kotlin" should open. Good job!

Please feel free to experiment around. When you alter some code, press Ctrl+F9 to recompile - the code should be deployed to Jetty immediately, just press F5 in the browser. If not, just head down to the Debug Tool Window and then press the green arrow "Rerun 'vaadin-app'", to recompile the project and restart the Jetty web server. If something's not working right or I am not explaining myself properly, please see the example application here: https://github.com/mvysny/vaadin-app

In the next blog post, we will add database support.