Showing posts with label Eclipse. Show all posts
Showing posts with label Eclipse. Show all posts

Wednesday, December 5, 2012

Reflections on writing an Eclipse plugin

For a personal project I'm working on, the language choice is C++. Now that's probably going to make a lot of readers cringe because C++ has some bad rep, especially with the black magic voodoo that goes by the name of Templates. However due to the requirements of the app, C++ was a good fit. It's not too bad if you apply SOLID principles, design patterns, and above all good naming conventions. IMO a major contributor to C++'s bad reputation is the extremely poor names people use (the STL doesn't help either). We can see the porting back to C++ of good design concepts, most notably in the tools. Libraries like Qt make it almost like having a JDK at ones fingertips (but with a decent UI system). Did you know you can do TDD in C++?

I use the Eclipse CDT for my IDE which when coupled with the Autotools plugin makes it really easy to edit and build my code with most of the features I get out of the Java tools in Eclipse. You don't get everything, but it does a good job.

One thing I was really missing was a way to generate test classes quickly. I use the Google C++ testing framework as it's the best I've found that matches JUnit or TestNG. It's a bit clunky given the state of Java test tooling, it's style is very much on par with JUnit 3, but given C++ doesn't have annotations, it does really well with some macro magic. One can still use BDD style testing with a few compromises to get your code to compile. What I was missing was a "Create test class" option to keep my productivity from getting bogged down in making sure my #includes were correct.

I've been wanting to write an Eclipse plugin for a while, so I thought I'd use this itch as a chance. Turned out it was a lot easier than I had thought.

I downloaded the RCP version of Eclipse as it comes with all the development tools for making plugins. I personally like to keep my Eclipse installs separate for different purposes. About the only common plugin I use across all of them is my Mercurial plugin. I installed the CDT on top of the RCP so that I had access to all the CDT JARs since I was developing a CDT focused plugin.

Starting on writing the plugin was really simple. Of course I googled around first and came across a few helpful links:

The thing that made the plugin development easy IMHO was the plugin configuration editor. I was dreading writing XML and getting it wrong (try debugging that), or writing properties to configure the build (and finding reference documentation to do what I want). Thankfully I didn't get any obscure errors, the editor did it all. Took the fear out of the project. Coupled with some extra helpful documentation on plugin terminology and what not to do; I got my first wizard up and running very quickly.

Since I was making a CDT based plugin, I needed to set my API baseline. This helps the compiler figure out if you've been doing naughty things. This is a real strength, because by letting you know when you've violated API boundaries, you're able to future proof your plugin against changes to internals; or at least tell (via your plugin conf) that you're willing to risk the consequences.

Since I was wanting to create a special instance of the "New Class" wizard option, I subclassed the relevant wizards and wizard pages classes. The one big frustration was that protected methods in these classes used private members, or private inner classes. Which meant that to override the behaviour (but still keep parent behaviour) some nasty reflection hacks were needed. I think the design moral there is that if you are going to allow your methods to be overridden make the data accessible (most likely through protected accessors). Either that or mark the methods as final so that the compiler lets you know that "you can't do that Dave". Unfortunately these CDT classes violate the whole Open Closed principle. Other than that it was actually pretty easy to debug my way through the "New Class" wizard to get an idea of how I could create a specialised class geared towards being a test class and writing the behaviour.

The bulk of the code was written on the train going to/from the YOW 2012 conference so hopefully that conveys just how easy it was once I got going. It's a credit to the PDT guys that banging out a plugin is that easy; in terms of the infrastructure code required to hook it in; I mainly had to work on application logic which is how it should be.

The final result is the Google Testing Framework Generator, so if you can make use of it, please download it and make suggestions/patches. I have a few other extra ideas of code this plugin can generate, but for now I'm just going to TDD my way faster through some new features for my C++ project.

Tuesday, November 29, 2011

Eclipse moving forwards

Most Java devs (and others too) have a love/hate relationship with Eclipse. Many a flame war debate has been had on the subject.

From my own personal experience, I think Eclipse is moving forwards in the right direction. Helios and Indigo both feel snappier, and the installation/upgrading of plugins is easier.

I had to upgrade my work instance of Eclipse and even though there were conflicting versions of different plugins, it was easier to resolve than in previous versions of Eclipse.

Some of the other language editors could do with some love (PHP for example) but overall I'm finding my productivity is increasing with the later versions of Eclipse and I have to wrestle with it less.

Monday, May 30, 2011

Integration is the mess that noone wants to clean up

The title for this post came as a rather tongue in cheek comment by the sys admin at my workplace. However I think this is a rather accurate description of a personal project that I've been working on for the past six months. This project was designed as an educational project into different technologies that I've wanted to play with; so a lot of the decisions were guided by that. Across the way I've thought about different issues, found different tips and tricks and thought I'd share them.

The goal of this project is an integration piece between a website (through RSS) and social media sites like Facebook, MySpace, and Twitter (with all the links fed back to the original site). The goal was to not have to replicate data across the multiple sites; as well as give me an excuse to play with new toys.

The runtime environment is Google App Engine as this app would run infrequently and GAE is free. I also have wanted to write a GAE app for a while, so this seemed like a good idea. The language is Java since that's my primary development language and I don't know Python.

The build tool is Ant as I despise Maven. I use Maven at work, and I find it to be inflexible, bloated and just plain annoying. It does have some good ideas however and given Ant's import abilities, one can write generic build tasks that implement good build practices without all the pain. I did consider other build tools like Gradle but I found personally that after thinking about what I wanted to do for a while I was able code the build declaratively with Ant being smart enough to handle all the heavy lifting. I'm considering Open Sourcing my Ant build library that I've accumulated when I've cleaned it up a little bit.

Maven also provides dependency management however I personally find Ivy's dependency management to be more mature, cleaner, simplier and easier to configure/use than Maven.

Discussions about build tools can often get people a bit hot under the collar and I found The Java Posse podcast on the subject to be very educational (as a hint they're not very Maven friendly).

My IDE of choice is Eclipse (Helios), with the relevant Google plugins. One other reason that I dislike Maven is that the M2 integration sucks (I've heard it's a lot better with Indigo however I've yet to try). However Ant was not immune from problems either in that the runtime I am using is 1.8.1, and the Ant build editor doesn't recognise syntax from that version so Eclipse tells me my build.xml has errors in it. Runs fine however.

For my SCM I'm using Mercurial as it is the best VCS around, beating Git by a gazillion miles (yes I have actually used Git in a sophisticated manner and Hg is so much easier and more intuitive).

The app itself is broken down into 3 parts (with Spring handling all the configuration). The first handles datastore/RPC services, with a GWT frontend, Spring MVC providing the CRUD RPC endpoints, and Objectify handling persistence. The second part is implementing the manual workflow of OAuth2 with Spring MVC rendering the views (very simple JSPs) and accepting callbacks. The third was the part that actually made posts to the social media sites and kept everything in sync.

I spent a lot of time trying to bash JPA to work on GAE, however the DataNucleus implementation is quirky at best. It does certain tasks (like the assigning of PK values) differently from all other JPA implementations and the JDO junk that gets stuck in you .class file can mess with other annotations or class behaviour. I spent one Saturday ripping out JPA and replacing it with Objectify (guided by tests for you TDD purists out there), and I've little trouble ever since.

A few big design principles that I've been trying to hammer into myself is good old DRY and others from the SOLID acronym like SRP; guided by tests. Working with a framework like Spring is that if you don't follow these ideas then you can get yourself into trouble quickly enough to realise something's amiss. For example even when using Objectify one still has to deal with transaction management. It's the same bit of code that runs for all DAOs so where do you put it? One should of course favour composition over inheritance. I went with an AOP (JDK proxy) approach where a transaction manager provides advice around the DAO methods, injecting an "entity manager" which the DAOs then used for DS operations. Very elegant but not as easy if one doesn't code to interfaces (the L of SOLID as I understand it).

However GAE itself doen't help with the testing side of these principles, and it's an area where Google could really improve their tooling, especially if they want more than Micky Mouse projects running on GAE. It's nigh impossible to preload the local DS file with test data for integration/acceptance tests (where the tests run in one JVM and the dev_server serving your app runs in another). I hacked a solution together but it broke when the SDK was updated. The only way therefore is to use an interface which you build into your app. Since most of my entities were being served in a XML representation over HTTP to be consumed by a GWT front end it wasn't too much of a pain to drive my tests through the browser using Selenium. However for a more sophisticated project it's a nail in the coffin for testability.

Learning Spring MVC was a joy, with the ability to render a view of the model (through JSP) or return data in a HTTP response body (ala REST/RPC) with minimal effort. As far as MVC frameworks go it's the best I've worked with to date. However there is some room for improvement with the way that Content-Types (MIME) are handled in an AJAX world, but I've detailed that problem before

Running code on GAE of course other than native servlets is annoying, which some readers may already know because of the way GAE attempts to serialize everything. I had to rework my atchitecture a bit to try and get around that, but I still get errors in the logs due to Spring classes not being Serializable.

I've probably left a few details out here and there, and questions/comments are welcome (unless you want to troll then bugger off). Constructive criticisms of technology choices are always interesting and I like to chig wag about that; although please don't start a flame war.

Overall I found this project to be satisfying and educational and I've come out the other side a better engineer/developer.

Wednesday, July 28, 2010

Upgrading to Helios

I use Eclipse as my primary IDE (cue the IntelliJ fan bois). Over the years my personal install of Eclipse has become bloated and cluttered, so with Helios I thought I'd start afresh.

A pleasant experience. To go with simplicity I chose Eclipse Classic, and have added in all the features I need, rather than have a bloated monstrosity. I have enjoyed the Eclipse Marketplace having a "one stop shop" for those needed plugins.

The result, a clean easy to boot, lean on the memory IDE.