Archive for the ‘Tools’ Category

JTL goes open-source

Posted on September 6th, 2008 in EN, Java, Tools | No Comments »

JTL, the Java Tools Language (pronounced “Gee-tel”), is a high-level query language for selecting program elements, designed to serve the development of source code software tools for Java.
It is both simple and powerful: you may use it for various source code tasks, from just finding all classes with print() method to executing an extremely complex refactoring transformation.

JTL is very easy to use, its intuitive query-by-example syntax makes it really easy to write JTL queries. For example,

public static double method(int, int);

matches all static methods that receive two int parameters and return a double. And the following query

classWithFactory := is T, class { 
    no public constructor; 
    public static T method;
}

matches all factory classes - classes having no public constructor, but instance factory method.

Additional JTL examples may be found in JTL Language Tour. The examples above come from this excellent manual too.

The JTL was initially described in the JTL - The Java Tools Language paper and developed at the Computer Science department at the Technion. But now, after a years of development, JTL goes open source at sourceforge. There is no blog or RSS feed there yet, but I hope those will appear soon.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

Hibernate annotations: The many-to-many association with composite key

Posted on July 19th, 2008 in EN, Java, Tools | 50 Comments »

Also many-to-many associations are usually referenced as a bad design solution, they are widely used in almost all modern database-centric applications (especially in those built around the existing legacy database). The very common scenario is a case when you not only need to handle a many-to-many association but also hold some additional property on the association.

In a J2EE world, Hibernate still remains the most popular ORM tool (or the JPA provider, if you wish). But implementing such a scenario with Hibernate Annotations is not so simple as you might imagine.

First of all, in the good old spirit of the Hibernate community, there is almost no documentation about many-to-many associations and composite keys (two paragraphs stating that there is @ManyToMany and @EmbeddedId annotations are not considered a documentation).

And the second hope of every open-source tool consumer, the world wide web community, provides almost no help: everybody are referencing the same post by Marcel Panse, written in April 2006. Though Marsel’s post is very clean and descriptive, it become outdated and the solution provided there is simply not working with the latest versions of Hibernate Annotations.

So I had to reinvent the wheel by my own, based on Marsel’s sample. Below is the solution working with Hibernate Annotations 3.3.1.GA.

The database part is the same: we have three tables (item, product and product_item), two POJO classes, and two classes for a many-to-many association and its primary key. The main difference from Marsel’s solution is that I’m not using any kind of “fake” properties on ProductItem in order to reference Item and Product, but just a plain transient properties delegating to ProductItemPk.

@Entity
@Table(name = "item")
public class Item {
 
    private Integer id;
    private String name;
    private List<ProductItem> productItems = new LinkedList<ProductItem>();
 
    public Item() {
    }
 
    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    @Column(name = "item_id", nullable = false)
    public Integer getId() {
        return this.id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    @Column(name = "name")
    public String getName() {
        return this.name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.item")
    public List<ProductItem> getProductItems() {
        return this.productItems;
    }
 
    public void setProductItems(List<ProductItem> productItems) {
        this.productItems = productItems;
    }
}
@Entity
@Table(name = "product")
public class Product {
 
    private Integer id;
    private String name;
    private List<ProductItem> productItems = new LinkedList<ProductItem>();
 
    public Product() {
    }
 
    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    @Column(name = "product_id", nullable = false)
    public Integer getId() {
        return this.id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    @Column(name = "name")
    public String getName() {
        return this.name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.product")
    public List<ProductItem> getProductItems() {
        return this.productItems;
    }
 
    public void setProductItems(List<ProductItem> productItems) {
        this.productItems = productItems;
    }
}

Note the two important points: ProductItem has two transient properties for Product and Item (since an unidirectional relationships will be meaningless here) and a use of @AssociationOverrides annotation to specify the database columns

@Entity
@Table(name = "product_item")
@AssociationOverrides({
@AssociationOverride(name = "pk.item", joinColumns = @JoinColumn(name = "item_id")),
@AssociationOverride(name = "pk.product", joinColumns = @JoinColumn(name = "product_id"))
        })
public class ProductItem {
 
    private ProductItemPk pk = new ProductItemPk();
 
    @EmbeddedId
    private ProductItemPk getPk() {
        return pk;
    }
 
    private void setPk(ProductItemPk pk) {
        this.pk = pk;
    }
 
    @Transient
    public Item getItem() {
        return getPk().getItem();
    }
 
    public void setItem(Item item) {
        getPk().setItem(item);
    }
 
    @Transient
    public Product getProduct() {
        return getPk().getProduct();
    }
 
    public void setProduct(Product product) {
        getPk().setProduct(product);
    }
 
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        ProductItem that = (ProductItem) o;
 
        if (getPk() != null ? !getPk().equals(that.getPk()) : that.getPk() != null) return false;
 
        return true;
    }
 
    public int hashCode() {
        return (getPk() != null ? getPk().hashCode() : 0);
    }
}
@Embeddable
public class ProductItemPk implements Serializable {
 
    private Item item;
    private Product product;
 
    @ManyToOne
    public Item getItem() {
        return item;
    }
 
    public void setItem(Item item) {
        this.item = item;
    }
 
    @ManyToOne
    public Product getProduct() {
        return product;
    }
 
    public void setProduct(Product product) {
        this.product = product;
    }
 
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        ProductItemPk that = (ProductItemPk) o;
 
        if (item != null ? !item.equals(that.item) : that.item != null) return false;
        if (product != null ? !product.equals(that.product) : that.product != null)
            return false;
 
        return true;
    }
 
    public int hashCode() {
        int result;
        result = (item != null ? item.hashCode() : 0);
        result = 31 * result + (product != null ? product.hashCode() : 0);
        return result;
    }
}

Hope this helps.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

The rule of thumb

Posted on January 3rd, 2008 in EN, Java, Tools | 1 Comment »

If you may configure something using Spring — never ever try to configure the same thing with Hibernate.

Sorry, Gavin.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

Is the modern software getting more and more humanlike?

Posted on December 20th, 2007 in EN, Tools | 2 Comments »

The colleague of mine just got this from his IntelliJ IDEA 7.0.2:

idea_cannot_message.gif

At least it apologizes…

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

Playing around with IntelliJ IDEA 7

Posted on October 30th, 2007 in EN, Java, Tools | 1 Comment »

There is something charming in those small things IDE developers make for us.

idea7-lookup.png

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

Back to hashCode() mutability

Posted on May 29th, 2007 in C#, EN, Java, Tools | 4 Comments »

My «HashSet.contains(): does your basket contain something?» post got too expected responses: «There is no way to avoid this behavior, why should you expect something else?».

Sure this behavior can not be changed — it’s in nature of any hashed collection. I do not expect anyone to tilt at windmills. What I do expect is, first, ensure I will never stuck with this bug again and, second, prevent others from falling into the same trap. And this is definitely the point I expect the software vendors to help me.
Let’s look one more into the root of the problem: hash code should not be mutable while the entity exists in the collection. Actually, since we can newer be sure it does not, the hash code should never change since the entity was created. Thus, hash code calculation should be independent of object state, i.e. of its mutable fields.

Thus, the following suspicious code patterns should get a special attention in this context (I’ll generally use Java notation, the C# variation is trivial):

  • Mutable hash code: hashCode() accesses fields that are not final, or calls methods that access fields that are not final or call methods that… and so on.
  • Using overridden hashCode(): an instance of class with overriden hashCode() is added into hash-based collection (or one of its interfaces). More general - to any collection instance.
  • Broken contract: hashCode() and equals() do not access the same fields or do not call the same methods (that do not access the same fields… and so on).

What can prevent or warn us about the patterns mentioned?

  • Language level: not really can be taken into account, since providing language-level object identity is almost equal to just forbidding hashCode() override.
  • C# 3.0 anonymous classes make use of similar approach - the hash code of an object is immutable since both equals() and getHashCode() are compiler generated and both fields and properties are read-only.

  • Compiler warning level: may be nice, also implementing recursive method inspection will require new paradigms definition and will add unnecessary complexity. In addition, this require implementing this functionality separate for each platform language.
  • Code inspection: the most desirable option that should act at bytecode level and can be easily integrated into existing IDEs.
  • IntelliJ IDEA 6 inspections list presents a good inspection for mutable hashcode, and something not so powerful for broken contract.

This small and annoying point is just a tiny part of features missing from existing IDEs (expected to provide developer with an ability to concentrate on application business logic development rather than on language or infrastructure implementation details).

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

One mystery less

Posted on March 25th, 2007 in EN, Tools | No Comments »

I was always curious to know what is the engine behind the Miguel’s blog, and now there is an answer from his own.

Lame Blog looks both powerful and simple enough to suit my needs. I think I’ll try it soon.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

My private IDE war : small things make a big difference.

Posted on December 11th, 2006 in EN, Java, Tools | 7 Comments »

For the last three years I need to develop in both Java and C# side-by-side, which means almost simultaneous work with different IDEs. Thus the simple and intuitive interface is a must for keeping a productivity pace. And probably the most used and critical feature is a hot key shortcuts for navigating, debugging, refactoring and so on.
Ideally, I’d like to have the same hot key scheme in all my IDEs, so there will be no need to learn and remember how to do the same things twice.
I’m usually working with three commons: VisualStudio 2005, Easy Eclipse and IntelliJ IDEA.
So, what are the offerings?

  • Visual Studio 2005
    “Options -> Keyboard” dialog offers you eight different hot key mapping possibilities that can suite almost anyone used to work with Microsoft tools once. No surprise here: Microsoft, as usual, cares about “their” developers only, but provides a perfect solution.
    Visual Studio 2005 key mappings
  • IntelliJ IDEA 4.5
    “IDE Settings -> Keymap” has four built in possibilities including Mac OS X and Visual Studio schemes. Mac OS X scheme is nice, Eclipse bindings seems to be missing, but Visual Studio is surprising: “wow, they even remember about those migrating from .Net to Java!”. I did not check the later versions, but its probably not worse.
    Intellij IDEA key mappings
  • Easy Eclipse 1.2.1
    “Preferences -> General -> Keys” gives a two possibilities: default and emacs. These guys do not care about anyone using any tool other that their own? Don’t worth a screenshot.
    The most annoying thing is that they do think about this feature: Eclipse has a quick assistance for a hot keys, creating and modifying key bindings is an issue, developers complain about feature weakness and still nothing is done.

The very sad bottom line is: do not expect extra attention to your needs unless you pay…

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo

Bytecode viewer tools: Jclasslib vs Classfile Inspector.

Posted on August 24th, 2006 in EN, Java, Tools | 2 Comments »

Comparison overview of bytecode viewer applications Jclasslib Bytecode Viewer 3.0 by ej-technologies and Classfile Inspector 2.0 by Industrial Software Technology.

Introduction

Recently I faced with a need to inspect a Java bytecode in order to create a tests for bytecode processing application. Googling around showed that the market of the bytecode viewers is narrow and actually there is no large variety of possibilities to choose from.

Viewing Java bytecode generated from the Java source is not too common task for most Java developers, so the choice of the tools in this area is quite narrow. In addition to the bytecode viewers discussed here I’ve found the following additional tools:

Feature comparison table

Jclasslib Bytecode Viewer 3.0 Classfile Inspector 2.0
General
Pricing Free 10�-99� per license (depends on license amount), free for students and
teachers
License GPL Commercial
Supported platforms Windows, Linux, Unix, Mac OS X 10.1/2 Windows, Linux and others (as plugin)
Installation Platform-specific installation package Jar file. Requires write privileges
Available plugins NetBeans module Eclipse 3.1 (and higher) plugin
Standalone version Yes No
Java versions supported 1.5 1.5
Usability Works smoothly Changing default output directory breaks an ability of viewing *.class file corresponding to java source
Features
Presentation Application windows Text file
Bytecode hierarchy presentation Application window “Outline” Eclipse view
Hierarchy link with bytecode editor Yes Yes
Viewing standalone *.class files No Yes
Exploring *.jar files Yes Yes
Binary data presentation No Yes
Bytecode presentation Yes. Separate presentation for each type (methods, fields, exceptions etc.) Yes. All-in-one text file containing binary data, bytecode instruction presentation and source code
Java source presentation No If available in project
Bytecode decompilation No No
Bytecode modification No Yes
Bytecode validation No No
Links inside bytecode Yes No
Export Method bytecode instructions can be copied to clipboard As any text file

Pros and cons

Jclasslib Bytecide Viewer 3.0
Pros:

  • Availability as a standalone application
  • Links inside bytecode presentation

Cons:

  • Limited export ability
  • No binary data presentation
  • No source code presentation

Classfile Inspector 2.0
Pros:

  • Eclipse integration
  • Mixed binary, instructions and java source presentation
  • Bytecode modification

Cons:

  • No available as standalone application
  • Limited usability

Summary

Classfile Inspector 2.0 is a very powerful bytecode viewer application, with good presentation features, giving an ability of inspecting bytecode created by compiler as a derivative of java source code. This provides a user with an opportunity to understand deeply the way bytecode is generated and the affects of different coding decisions on actual code execution. It looks to be an ultimate helper for anyone teaching or studying Java. The main application disadvantage is its tight binding to Eclipse platform, making it almost useless for those working with any other Java IDE.

Jclasslib Bytecide Viewer 3.0 is a good tool for developer that needs just an inspection view on the jar files containing bytecode created, with no ability to modify it or to follow the influence of source code changes on the bytecode generated. Plugins for IDEs other that NetBeans would be nice, even it always can be used as a standalone application.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Technorati
  • Reddit
  • Scoopeo