Changing font in Skitch

I was recently googling how to change the font of the text widget in Skitch and found this answer :

Transcript:

This seems really basic, but I can’t for the life of me figure out how to change the text’s font in Skitch. What am I missing?

Evernote employee: You currently cannot change the font. This is on our long-term roadmap.

That post is over a year old. Must be quite an engineering challenge…

UX Design Disasters: Stormpath

While Stormpath claims to offer ‘User Management’ in all their online ads, sadly after using their service on DripStat, that is exactly what we have lost.

Here is an image of Stormpath’s dashboard to ‘manage your users’.

Yes, thats right. If i want to see details of any user of DripStat or perform any function on it, I have 2 choices:

  1. Click ‘next’ at the bottom of the page. Browse through all the 20,000 users of DripStat, 25 at a time, to reach the ‘one’.
  2. Write a custom program to do that.

Utter UX Fail

On a scale from 1 to 10, this is UX fail to 11. User management is the core service that Stormpath claims to offer and even after many months they haven’t bothered fixing such a critical issue with their interface.

If we had just created a ‘users’ table in our database, life would be so much simpler…..

Firebase’s Java SDK will screw your app server and deployment scripts

We use Firebase a ton at DripStat. So I am sad to see firebase basically not giving a flying f**k about their Java SDK.

Your web applications can no longer shut down

The Firebase SDK creates background non-daemon threads, so when you try to shutdown your apache tomcat using the ./shutdown.sh script, it wont. Your tomcat will continue running until you manually use the kill command on the process to kill it.

Deployment processes get screwed

Any tool/script that executes ./shutdown.sh on your tomcat server to kill it, will result in crazy errors cause while the script will execute and think tomcat is terminated that won’t in fact be the case. Tomcat will continue running until its manually terminated as described above.

Even in development, an extra step to remember

It even screws your development, since no longer does pressing the ‘Stop’ button in Intellij terminate Tomcat. You have to remember to ‘kill’ tomcat using a separate button after you press the stop button.

Website has no info

Not only that, the website has no changelog or version history of their sdk artifact making it impossible to know when the sdk is updated and with what changes.

Conclusion

It is surprising that Firebase has completely ignored such a major issue which impacts both development and production time continuous delivery processes.

Guide on using Java 8 in Eclipse

An engineer from Zeroturnaround writes that he had such a bad experience enabling Java 8 support on Eclipse, he switched to Netbeans.

However, it took me 4 days after Java 8 release to find a blog post about the topic, which in turn refers to another message, which then points to a Wiki page that describes Eclipse’s support for Java 8. ) that refers to a message on the JDT mailing list which in turn refers to a Wiki page where a how to for Eclipse Java 8 support is described.

I am just assuming that he sucks at looking up stuff. Here is how to ‘find’ and enable Java 8 support on Eclipse:

1. Go to eclipse.org and read the topmost headline

2. See full page with instructions and images

Is that so hard….

UX Design Disasters: Perforce Eclipse plugin

The Perforce Eclipse Plugin has the P4 Pending Changelists view to see your changeslists and submit them.

The toolbar has a bunch of buttons. But its missing a key one.

So umm how does one actually ‘submit’ a changelist??

The button you want to use 99.9% of the time is hidden in the right-click menu…

This is what happens a product is designed by someone who doesnt use it himself.

ASM framework 5.0: The missing migration guide

I just upgraded both DripStat and Chronon to ASM framework 5.0 to support Java 8. Apparently there is no migration guide for upgrading from asm 4 to asm 5 which caused a ton of issues.

Here is the list of those issues and their solutions so you don’t have to face them too:

1. Change to Opcodes.ASM5
Everywhere that you pass Opcodes.ASM4, replace with Opcodes.ASM5. This one is the most obvious.

2. Change onVisitMethodInsn() overrides
This one will cause you tons of subtle runtime bugs if you don’t know about it.

Issue:
ASM 5.0’s MethodVisitor contains a new visitMethodInsn() method with the signature:

void visitMethodInsn(int opcode, String owner, String name,
  String desc, boolean itf) 

Note the addition of the last parameter boolean itf which is to support default methods in Interfaces.

If you pass Opcodes.ASM5, the MethodVisitor class will only call this method. So your pre asm 5 code that uses the visitMethodInsn() method without the boolean itf parameter will never be called! Of course, this means that your code will compile and you won’t even get a RuntimeException. Just that since your visitMethodInsn() is never called, you will have bugs in the instrumented code.

Solution:
Replace overrides to visitMethodInsn() with the new version. Your IDE should be able to help you here by marking the previous version of the method as deprecated.

3. Changed your ClassNode subclasses
Do you have a class that extends from ClassNode like this:

class JSRInliningClassNode extends ClassNode {
        public JSRInliningClassNode() {
            super();
        }
}

This will cause a RuntimeException because ClassNode's no-arg constructor looks like this:

public ClassNode() {
        this(Opcodes.ASM5);
        if (getClass() != ClassNode.class) {
            throw new IllegalStateException();
        }
    }

Solution:

Use the constructor that does take an argument, the code should be like this:

class JSRInliningClassNode extends ClassNode {
        public JSRInliningClassNode() {
            super(Opcodes.ASM5);
        }
}

4. Use asm 5.0.1 atleast
ASM 5.0.1 was relased just a few days after the 5.0 release and contains some critical bugfixes. Make sure you use atleast that version.

Have fun!

A guide around Spring 4’s buggy Websocket support

While Websockets are indeed the big feature of Spring 4, they are also extremely buggy even after two revisions (version 4.0.2). We tried using them for DripStat but ended up switching to an 3rd party service after encountering all the bugs. This is a guide for some of the issues you will encounter and solutions for them.


1. Using an external queue throws ClassNotFoundException

Spring makes it real easy to use an external message queue like RabbitMQ for messaging. You just need to replace config.enableSimpleBroker("/topic"); with config.enableStompBrokerRelay("/topic”);.

Sounds awesome right. Well, that is until you make that change and run your program only to run into a ClassNotFoundException for reactor/tcp/TcpClient. At this point, you are probably confused. The Spring Projects page does not show anything by the name of ‘Reactor’ so what is this beast and why don’t the spring websocket docs mention it?

Apparently Reactor is a project by the spring people but not under the official Spring brand. And using an external queue causes Spring to switch to using Reactor, without telling you that it needs it.

Solution:
Just add the following dependency in gradle and you should be fine:
compile 'org.projectreactor:reactor-tcp:1.0.0.RELEASE’

Related bug: https://jira.springsource.org/browse/SPR-11449


2. Cannot authenticate with external queue

If you are using version 4.0.0 or 4.0.1, you may find yourself not being able to authenticate at all against your external queue. Apparently services like CloudAMQP and CloudFoundry require you to set a virtual host for your queue and prior to version 4.0.2 there was no way to set that!

Solution:
Upgrade to version 4.0.2 and call setVirtualHost() in the StompBrokerRelayRegistration instance.

Related bug: https://jira.springsource.org/browse/SPR-11433


3. CORS filter breaks

If you use CORS and have a filter setup to add CORS headers, you will find that it breaks when used against spring’s websocket endpoint url. That is because just for the web socket endpoint, Spring decides to add CORS headers by itself, which will interfere with the ones you already added. Again this fact is not documented anywhere. It also seems that Spring’s filter doesn’t even bother to check if the CORS headers are already present so as to not interfere with them.

Solution:
Your CORS filter will need to check for and exclude adding CORS headers to the websocket endpoint (since Spring insists on adding them for you).

Related bug: https://jira.springsource.org/browse/SPR-11443


4. Tons of exceptions in logs

You may see tons of exceptions like these in your logs: ClientAbortException: java.net.SocketException: Broken pipe. This seems to result from this issue in the servlet spec. Again Spring neither has detection for this nor documents this issue.

Solution:
Vote/comment to get the bug resolved at https://java.net/jira/browse/SERVLET_SPEC-44

Related bug: https://jira.springsource.org/browse/SPR-11438


5. Websockets slow even after using external queue

While the docs continually harp on using an external queue for production usage, you may find that even doing so doesn’t solve all the performance issues with your app. It turns out it is not until you read the javadoc of the method WebSocketMessageBrokerConfigurer.configureClientInboundChannel() do you realize that Spring is using just 1 thread to do all the work. How are you supposed to stumble upon the javadoc of this particular method? No idea.

Solution:
Implement the WebSocketMessageBrokerConfigurer’s configureClientInboundChannel() and configureClientOutboundChannel() methods to return an executor with a thread pool size > 1.

Related bug: https://jira.springsource.org/browse/SPR-11450

Conclusion

While some of these may be resolved in future versions, the current release of Spring’s Websockets is undoubtedly very undocumented and buggy. That said I do think Spring has done an outstanding job architecture wise of making web sockets as simple to use as creating Rest APIs and i am looking forward to a more stable version.

Intellij downgrades Gradle support from version 12 to 13

This is the Gradle UI in Intellij 12 : You can see the exact dependencies of each project explicitly. There is separate tab that shows the tasks available for each project and even lists the most recently run tasks.

In Intellij 13, all this takes a backward step: Now only a list of tasks is shown.

  • No more tree of dependencies.
  • No more recently used tasks.

I dont see why Jetbrains decided to downgrade their Gradle support.

Update: Jetbrains has clarified that the ‘recently used tasks’ does work like in intellij 12.

Intellij IDEA And Its Config Files of Pain

There is so much fanboyism around Intellij being this mega-super-awesome IDE that totally leaves Eclipse in the dust. So a while ago I decided to try using Intellij as my main IDE for DripStat. As it turns out, there are tons of chinks in the armor. Take for example version controlling Intellij’s project files:

Eclipse

Now Eclipse has literally just 2 config files you need to checkin - .project and .classpath. They don’t modify themselves so often and the fact that there is only 2 of them makes them easy to manage if they do.

Intellij on the other hand:

Yes, 52 files for Intellij!

And that is in a very small project. Thats 52 different files you have to keep track of and will randomly add/remove change as you modify your project and its dependencies.

For some reason, Intellij has to generate a new file for every single library you use, even though there is a standard directory and naming conventions to store those libraries if I am using Gradle. And it wants to check them in.

Whats worse is how incompatible Intellij’s project files are. If one dev opens a project in Intellij 12 and other in Intellij 13, both will now have a broken project and an enormous amount of files they need to manage. And unless everyone upgrades there is no real way to figure out which version’s file to checkin. Also what is crazy is how randomly the files change. Just removing/adding the same library changes a whole bunch of files that I have no idea about.

Note that this goes not just for Intellij. Even with Webstorm 7, I have to constantly fight the IDE’s files against my own source code.

Managing Intellij’s project files is an absolute pain in the ass. Its more work than managing your source code and its useless work that one shouldn’t have to do. Eclipse does a far better job by keeping you from checking in those files to your version control.

At this point I have just stopped checking in Intellij specific files and moved them to a separate changelist (the one you see above). Jetbrains needs to clarify its guidelines on whether it wants developers to checkin IDE specific stuff. And if yes, then needs to provide a better way to manage them.