Showing posts with label netbeans. Show all posts
Showing posts with label netbeans. Show all posts

Friday, 19 September 2014

Maven and PlantUML

This blog explains about integrating PlantUML with Netbeans and Maven. For integrating PlantUML with Netbeans and Ant, see my previous blogpost here.

The blog at [2] explained to me how to add PlantUML to my Maven project, using the special plugin developed by jeluard1.

Just adding the following to the plugins did the trick:
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <groupId>com.github.jeluard</groupId>
    <artifactId>plantuml-maven-plugin</artifactId>
    <version>1.1</version>
    <configuration>
        <outputInSourceDirectory>false</outputInSourceDirectory>
        <outputDirectory>${basedir}/target/site/apidocs</outputDirectory>
        <sourceFiles>
            <directory>${basedir}/src/main/java/</directory>
            <includes>
                <include>**/*.java</include>
            </includes>
        </sourceFiles>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>net.sourceforge.plantuml</groupId>
            <artifactId>plantuml</artifactId>
            <version>8004</version>
        </dependency>
    </dependencies>
</plugin>

Netbeans and Maven

In Netbeans you can select Actions on your project to perform. There is a coupling between the action and the goals in Maven that are executed3.

These can be changed by going to your Netbeans Project Properties (right-click your project, select properties) - select "Actions" - select "Generate Javadoc".

Then add the plantuml Maven goal, com.github.jeluard:plantuml-maven-plugin:generate. You're likely to end up with the following:
generate-sources javadoc:javadoc com.github.jeluard:plantuml-maven-plugin:generate

References

[1] GitHub - jeluard/maven-plantuml-plugin
https://github.com/jeluard/maven-plantuml-plugin
[2] Smartics - Using PlantUML
http://www.smartics.de/archives/1313
[3] Netbeans - MavenBestPractices
http://wiki.netbeans.org/MavenBestPractices

Friday, 12 September 2014

Moving From Ant to Maven

My project "karchangame" is Ant-based, basically because when you create a new project in Netbeans, the Ant configuration is the default.

This has worked well for a long time, until I decided recently to upgrade some of the libraries that I use. Now, in Ant, you just download the libraries you need and put the jar-files in your classpath.

That works fine if your libraries are not complicated. But I noticed that some of my libraries are now dependant on yet other libraries.

In short, I just spent an hour in getting the libraries I need, then getting the required libraries of those libraries, ad infinitum.

Maven takes care of this whole slog, by putting the responsibility for defining the required libraries for a framework/library squarely on the shoulders of that framework/library.

What I was stuck with was finding the best way of changing my Ant-based project into a Maven-based project.

Moving from Ant to Maven


The easiest way that I could come up with is to create a brand new Maven-based project. The original was a Web Application, so the new Maven project should also be a Web Application. As far as I could tell every possibility for a new ant-based project is also available as a new maven-based project.

And then start moving files over to the appropriate place in the new Maven structure.

I really like the fact that Git actually detects these moves instead of like in the old days, when a move was an explicit delete and create of two non-related files, making you lose your entire history of that file.

The difference in the directory structure is as follows:
You do notice that Maven actually has a more layered structure, whereas Netbeans Ant basically dumps everything in the root.

So, the move basically entailed the following:
From antTo Maven
build.xmlpom.xml
-nb-configuration.xml
nbproject-
lib- (actually stored in your m2 repo)
src/confsrc/main/resources
src/javasrc/main/java
websrc/main/webapp
testsrc/test/java
buildtarget
dist/karchangame.wartarget/karchangame-1.0-SNAPSHOT.war

Pom.xml

I only needed to make a few changes to my pom.xml file, in order to get all the dependencies sorted out.

JMockit

Needed to add JMockit, or my testcode didn't compile.
<dependency>

    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.10</version>
    <scope>test</scope>
</dependency>

AntiSamy

AntiSamy to prevent evil hackers from gaining access.
<dependency>
    <groupId>org.owasp.antisamy</groupId>
    <artifactId>antisamy</artifactId>
    <version>1.5.3</version>
</dependency>

URL Validation

<dependency>

    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.4.0</version>
</dependency>
It's amazing to see Maven automatically download all the required libraries.

The last part was adding plantuml back into the mix. But I'll talk about that in the next Blog.

References

Apache Maven
http://maven.apache.org/
Netbeans - MavenBestPractices
http://wiki.netbeans.org/MavenBestPractices

Wednesday, 23 April 2014

NetBeans 8.0 - Upgrading My Source Code

I have heard that in NetBeans 8.0, which has full support for the new Java 81, you can have your source code transformed to make use of the latest and greatest Java 8 has to offer.

Naturally, I wish to test this. I've chosen my YPPO project for it.

Progress


It seems easy enough. Just select Source in the main menu and choose Inspect2.

It transpired that I require FindBugs to use All Analyzers, but NetBeans automatically asked if I wanted to install it.

A lot of the inspection messages are regarding missing JavaDoc. I'm going to skip over those (as being not interesting).

Functional Operations

Use functional operations instead of imperative style loop.
public static void addErrorMessages(List<String> messages)
{
    for (String message : messages)
    {
        addErrorMessage(message);
    }
}
Got turned into:
public static void addErrorMessages(List<String> messages)
{
    messages.stream().forEach((message) ->
    {
        addErrorMessage(message);
    });
}

private void persistGalleries(Map<String, Gallery> galleries)
{
    for (String path : galleries.keySet())
    {
        Gallery gallery = galleries.get(path);
        logger.log(Level.FINE, "persistGalleries persist gallery {0}.", gallery);
        galleryBean.create(gallery);//em.persist(gallery);
    }
}
Got turned into:
private void persistGalleries(Map<String, Gallery> galleries)
{
    galleries.keySet().stream().map((path) -> galleries.get(path)).map((gallery) ->
    {
        logger.log(Level.FINE, "persistGalleries persist gallery {0}.", gallery);
        return gallery;
    }).forEach((gallery) ->
    {
        galleryBean.create(gallery);
    });
}

Lambda Expressions

Anonymous inner class creation can be turned into a lambda expression.
Collections.sort(list, new Comparator<Gallery>()
{
    @Override
    public int compare(Gallery t, Gallery t1)
    {
        return t.getCreationDate().compareTo(t1.getCreationDate());
    }
});
Got turned into:
Collections.sort(list, (Gallery t, Gallery t1) -> t.getCreationDate().compareTo(t1.getCreationDate()));

Notes


Despite NetBeans telling me that everything is perfectly fine, actually deploying it to GlassFish using the new Streams throws an ArrayIndexOutOfBoundsException. See [3].

I'm sure they're already hard at work.

References

[1] Overview of JDK 8 Support in NetBeans IDE
https://netbeans.org/kb/docs/java/javase-jdk8.html
[2] 7.11.21 Using Hints in Source Code Analysis and Refactoring
http://docs.oracle.com/cd/E40938_01/doc.74/e40142/build_japps.htm#NBDAG613
[3] Collection streams provoke java.lang.ArrayIndexOutOfBoundsException
https://java.net/jira/browse/GLASSFISH-21014

Tuesday, 18 March 2014

Netbeans : Oracle's IDE for the Java Platform

Transfer Solutions, a consultancy, education and managed services company in Leerdam provides a Transfer Café every month. Since last year it has been open to non-Transfer Solutions personnel. I decided to go Thursday, 13th of March 2014, 18:15 as I was interested in the subject matter discussed that evening.

There to tell us all about NetBeans was the Principal Product Manager, Geertjan Wielenga1, of Oracle.

One of the reasons for the existence of NetBeans, is that Oracle would look silly to release a brand new version of Java or JEE, and not have anything available for Developers to play with it. We as developers would have to wait until Eclipse, JDeveloper or IntelliJ catches up. So it just has an excellent upside for them.

One of the advantages of Java and JEE is that they are standards. This means there are definitions for what file does what and goes where and what format it can have. This makes it ideal for IDE's to automatically generate entire file structures based on user choices.

One of the primary requirements for NetBeans is to provide an extremely (seriously!) low threshold to start designing Java and/or JEE software.

Some of the items that came up during the talk:
  • NetBeans makes it very easy to start learning and programming for a starting Java developer.
  • NetBeans has everything! And if it doesn't have it, it is likely that you won't need it.
  • NetBeans has good integrated Maven support
  • Tutorials can provide you everything from a simple HelloWorld application to an entire Web Application Online Shopping cart on an Application Server
  • NetBeans Website apparently has a weekly Newsletter.
  • NetBeans can show you the Graph of your Maven Dependencies, and you can change the graph, and therefore mutate your dependencies, and export it to image. How cool is that?
  • NetBeans supports The Cloud, for example Amazon Beanstalk out of the box.
  • You can easily import your Eclipse Coding Guideline Settings (formatting and the like) into NetBeans.
  • There's a hook that allows you to automatically do stuff to a file right before you try and save it. For example "Organize imports". (Tools-Options-Editor-On Save)
  • Working with many different projects, it is difficult (especially when using multiple branches) to see to which project the file you are editing belongs. Therefore you can have coloured tabs! (Tools-Options-Miscellaneous-Windows)
  • If you are like some people, that have many files open in the editor, it gets difficult to keep track of them all. There are many solutions. One is the possiblity to indicate that you wish to see multiple lines of tabs (instead of scrolling). (Tools-Options-Miscellaneous-Windows)
  • In order to change the font-size of the editor (for example during presentations), try Alt-MouseScroll.
  • To easily change a lot in a file in the editor, try "Blockselection".
  • There is a nice GUI designed for Swing. Unfortunately, if you wish to use a GUI designer to create JavaFX user interfaces, you are forced to use SeamDesigner, an external tool.
  • NetBeans has integration possibilities for PhoneGap
  • NetBeans can easily be used for developing HTML5, CSS and JAVASCRIPT by means of plugins to the Chrome browser. Updates to your web files will be immediately visible in the Chrome browser, without even saving the file. Also, selecting an element in the Chrome browser, will immediately show you where in which file the item is put.
  • NetBeans has support for several Javascript frameworks. Especially AngularJS seems to be very easy to use.
  • Bookmarks is a very nice feature allowing you to bookmark lines of code to jump back to when you need it.
  • NetBeans is well integrated with Bug reporting tools, like Bugzilla and JIRA.

My Questions


Software integration, how does it work?
NetBeans provides, in the Services Tab, several hooks into for example Jenkins. Interesting tidbit is that the only difference between Jenkins and Hudson plugin is the Name.
How well works NetBeans with Android Development?
Well, there's a plugin/project that is being actively developed by some people called NBAndroid5. Currently there is nothing native set up in NetBeans and there won't be for the foreseeable future. The NBAndroid project could use some funding, though.
JavaDoc, why is it in a separate tab? Why not similar to Eclipse, where it shows up as a tooltip under the mouse cursor?
Interesting that you should mention it. It was a much requested feature by (former?) Eclipse users, and has been implemented in NetBeans 8.0
What is your experience with Plugins? Compared to, for example, Eclipse, where some are able to destabilize the IDE?
Well, since a lot of what you need is already available in NetBeans without the need for Plugins, the plugins landscape is not as vast as Eclipse. With that in mind, the core functionality of NetBeans is already very big, and very very stable.
Do you eat your own dogfood?
Well, of course! We develop NetBeans inside NetBeans.
How do you keep a big beast like NetBeans contained?
NetBeans is actually designed to be very modular with loose coupling, so there are teams working on the different modules of NetBeans. It works out very well. For more information on how we as developers can make use of this modularity for our own applications, see the chapter on NetBeans Platform below.
What does NetBeans use? Maven or Ant?
Ant is the default. If you choose "Create Java Application", you will get an Ant-build java project. Select "Maven Projects" if Maven is what you need. If you wish to port your application that was created using Ant to Maven, you have to do it by hand. There are no convenient tools for doing it for you.

NetBeans as a Platform

NetBeans as a Platform (Let's call it NAAP, I've not heard the term before anywhere, but it's going to have to start somewhere.) is a way of leveraging NetBeans to quickly build a Rich Desktop Application using Modular components, of which NetBeans itself is composed.

You can build your own Rich Desktop Application, in the same way that NetBeans does it. And let's be honest here, NetBeans is doing a fine job.

The advantages are legion:
  • can accommodate many users
  • can support very large applications
  • can create applications for 'the long haul', need to be stable and extendable for many years
  • can accommodate many applications, large organizations with many users usually do not have one single application, but often over a hundred.
  • modularity is key here, in order to keep maintenance manageable and development in parallel between different teams
  • loose coupling, between modules, is also key
  • can provide a consistent UI over many applications, while you can focus on the Business Logic. No more applications that are notorious for their flawless business logic and their crummy UI/Layout/Mainframe Forms, but flawless looking clients.

For screenshots see [2].

References

[1] GeertJan's Blog
https://blogs.oracle.com/geertjan/
[2] NetBeans as a Platform
http://platform.netbeans.org
[3] NetBeans Platform for Beginners
http://www.leanpub.com/nbp4beginners
[4] Transfer Solutions Presents: Transfer Café: NetBeans: Oracle's IDE voor het
Java Platform
http://eventreg.oracle.com/profile/web/index.cfm?PKWebID=0x514725fdc&source=WWPN13024859MPP133&goback=.gde_2120_member_5836764236474249217
[5] NBAndroid
http://www.nbandroid.org/
Adam Bien - Nothing compares... to NetBeans
http://www.adam-bien.com/roller/abien/entry/nothing_compares_8230_to_netbeans


Monday, 9 April 2012

JDK7 EJB3.1 and Netbeans Project (Part III) - Testing

Part I - Introduction, Part II - Hibernate and Transactions, Part III - Testing

Netbeans + TestNG


I have been trying out TestNG and JMockit in the new Netbeans. [1]

TestNG has become a standard part of Netbeans, that is, if you download the Nightly builds[2] of Netbeans. There is no longer a need to install the plugin from contrib. I used it, and I was suitably impressed.


In Bugzilla you can file bugs under "java/TestNG".

JMockit


I do like adding JMockit to my testing, because I've gotten used to mocking all the classes that I am not interested in and being able to provide their behavior in the tests. Especially handy to prevent having to use a database.

In this case, this was easy as pie. Just download[3] and add the jmockit.jar to the testing libraries, and away I went.


Results


An example of what the results look like in Netbeans can be viewed at [2]. I like the test reports generated, though, they provide a deal more information on what is going wrong.


References


[1] Netbeans - TestNG
http://wiki.netbeans.org/TestNG
[2] Netbeans - Nightly Builds
http://bits.netbeans.org/download/trunk/nightly/latest/
[3] JMockit
http://code.google.com/p/jmockit/
The JMockit Testing Toolkit Tutorial
http://jmockit.googlecode.com/svn/trunk/www/tutorial.html
Unit Testing With TestNG and JMockit
http://java.dzone.com/articles/unit-testing-with-testng-and-j

Wednesday, 29 February 2012

JDK7 EJB3.1 and Netbeans Project (Part II) - Hibernate and Transactions

Part I - Introduction, Part II - Hibernate and Transactions, Part III - Testing

Hibernate LazyInitializationException


In a Model-View-Controller pattern, the part that deals primarily with Transactions and Hibernate is the Model. This means the View, that needs the data to render the result to the user, is outside the transaction and in Hibernate this often causes LazyInitializationExceptions. Especially when traversing to proxies of collections inside the entities. In order to prevent this there are several solutions described in Open Session In View(1) article.

They are summarized below.
  1. use an interceptor, when the server is hit automatically start a transaction, when the result is transmitted back, automatically close/commit the transaction
  2. just make sure the Model provides all the data to the View, so the view does not run into the LazyInitializationException.
  3. have the view open a new transaction to retrieve the data, after the model is finished (which is a really really bad idea)
  4. have the framework deal with it
I prefer the last option, have the framework deal with it. At work, for example, this is done by using JBoss Seam and I must say, I've never had to deal with LazyInitializationExceptions.

Enterprise Java Beans - The Old Way


The good part of Enterprise Java Beans is that they provide the transaction support on the container level, so you, as a developer, do not need to be concerned with it. The bad part is that to access a Enterprise Java Bean requires either another Enterprise Java Bean or a call to the InitialContext. Like in the code below.

/**
 * Retrieve my gamebean.
 */

private GameBeanLocal lookupGameBeanLocal()
{
    GameBeanLocal gbl = null;
    try
    {
        javax.naming.Context c = new InitialContext();
        gbl = (GameBeanLocal) c.lookup("java:global/game/game-ejb/GameBean!mmud.beans.GameBeanLocal");
    } catch (NamingException ne)
    {
        itsLog.throwing(this.getClass().getName(), "lookupGameBeanLocal", ne);
        throw new RuntimeException(ne);
    }
    itsLog.exiting(this.getClass().getName(), "lookupGameBeanLocal");
    if (gbl == null)
    {
        throw new NullPointerException("unable to retrieve GameBean");
    }
    return gbl;
}
This is the code usually used in the WAR file of your EAR file to contact your Enterprise Java Beans. Any Hibernate entities the EJBs return suffer from the LazyInitializationException.

Enterprise Java Beans 3.1


But now, there's Enterprise Java Beans 3.1 which solves this problem, by the following new items:
  • EJBs can be contained inside your WAR
  • Context and Dependency Injection works in most (more) cases

For example the following Enterprise Java Bean was put inside the WAR, and annotated with REST Annotations and uses Hibernate Entities.

/**
 * Comment Enterprise Bean, maps to a Comment Hibernate Entity.
 * @author mr. Bear
 */

@Stateless
@Path("/comments")
public class CommentBean
{
    @PersistenceContext(unitName = "myDataSource")
    private EntityManager em;

    @EJB
    JobBean jobBean;

    protected EntityManager getEntityManager()
    {
        return em;
    }

    public CommentBean()
    {
    }

    @POST
    @Override
    @Consumes(
    {
        "application/xml""application/json"
    })
    public void create(Comment entity)
    {
        getEntityManager().persist(entity);
    }

    @PUT
    @Override
    @Consumes(
    {
        "application/xml""application/json"
    })
    public void edit(Comment entity)
    {
        getEntityManager().merge(entity);
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") Long id)
    {
        getEntityManager().remove(find(id));
    }

    @GET
    @Path("{id}")
    @Produces(
    {
        "application/xml""application/json"
    })
    public Comment find(@PathParam("id") Long id)
    {
        return getEntityManager().find(Comment.class, id);
    }
}

The Entity has appropriate annotations to indicate it can be converted to JSON and/or XML.
/**
 * Comment Entity mapped to the Comment table in the database.
 * @author mr. bear
 */

@Entity
@Table(name = "Comment")
@XmlRootElement
public class Comment implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Long id;
    @Size(max = 255)
    @Column(name = "author")
    private String author;
    @Basic(optional = false)
    @NotNull
    @Column(name = "submitted")
    @Temporal(TemporalType.TIMESTAMP)
    private Date submitted;
    @Lob
    @Size(max = 65535)
    @Column(name = "comment")
    private String comment;
    @JoinColumn(name = "galleryphotograph_id", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private GalleryPhotograph galleryphotographId;

    public Comment()
    {
    }

    public Comment(Long id)
    {
        this.id = id;
    }

    public Comment(Long id, Date submitted)
    {
        this.id = id;
        this.submitted = submitted;
    }

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public String getAuthor()
    {
        return author;
    }

    public void setAuthor(String author)
    {
        this.author = author;
    }

    public Date getSubmitted()
    {
        return submitted;
    }

    public void setSubmitted(Date submitted)
    {
        this.submitted = submitted;
    }

    public String getComment()
    {
        return comment;
    }

    public void setComment(String comment)
    {
        this.comment = comment;
    }

    @JsonIgnore
    @XmlTransient
    public GalleryPhotograph getGalleryphotographId()
    {
        return galleryphotographId;
    }

    public void setGalleryphotographId(GalleryPhotograph galleryphotographId)
    {
        this.galleryphotographId = galleryphotographId;
    }
}
And, voilĂ , no more LazyInitializationExceptions, no more retrieving EJBs through the InitialContext, no more EARs containing WARs and EJB JARs.

Infinite Recursion


One of the problems that occur, when you do NOT have any LazyInitializationExceptions, is Infinite Recursion. This happens when your Hibernate entities refer to each other, and in a REST service, Jersey tries to flatten the structure into JSON or XML for transmission.

This could be the case, in the example above, if there was a collection of comments in galleryphotograph, and a reference to the respective galleryphotograph in the comments.

In order to solve this, make sure to use XmlTransient and JsonIgnore at appropriate places.

Conclusion


The last paragraph "Can't this be done easier" in the Open Session In View is awesome. It provides the answer that the framework should handle all the transaction management, instead of yourself having to provide it.

And now this time has come! The new EJB 3.1 version allows you to put EJBs right there in your WAR! Either as a separate JAR file, or as class files. The same classloader will pick them up and you can use them in your classes via Dependency Injection as much as you like!

It does mean there is no modularization, but in my experience modularization is only a requirement for the exceptionally high-end big projects.

References

Open Session In View
https://community.jboss.org/wiki/OpenSessionInView
Data Transfer Objects
http://martinfowler.com/eaaCatalog/dataTransferObject.html
Wikipedia : Data Transfer Object
http://en.wikipedia.org/wiki/Data_transfer_object
Java Persistence With Hibernate
Christian Bauer, Gavin King
Is Java EE 6 War The New EAR? The Pragmatic Modularization And Packaging
http://www.adam-bien.com/roller/abien/entry/is_java_ee_6_war

Sunday, 19 February 2012

JDK7 EJB3.1 and Netbeans Project (Part I) - Introduction

Part I - Introduction, Part II - Hibernate and Transactions, Part III - Testing

Introduction


I've tasked myself with learning the new things available to JDK 7 and EJB 3.1 and how they integrate with Netbeans. In order to so do, in my experience, it is most gratifying to pick up a new project using these new technologies.

In this case, as at the time, I was wondering what to do with my old Photographs, I've decided to start up a project called YourPersonalPhotographOrganiser, which is nothing more than a simple Photo Gallery.

You can find the netbeans project on github at https://github.com/maartenl/YourPersonalPhotographOrganiser. Just check it out into your ~/NetBeansProjects/YourPersonalPhotographOrganiser directory, and see how far you get.

It's a work in progress, but it's at the stage where there's something more or less workable. Let me remind you that this software is for use at your own risk. Use it locally, as there is NO security (neither authentication nor authorization) implemented at the moment.

Requirements


  1. simple database, easy to make changes directly, if so required
  2. used for home use
  3. no authentication or authorization required
  4. helps me to understand the jdk 7, glassfish and jee 3.1, by using all the new stuff in there.
  5. absolutely NO changing of the photographs, all changes are done in java, in memory, in glassfish.*
  6. flexible in where these photographs are located (no need to keep them in the webdir, for example)

*) I've had too many instances where:
  1. changing files from webinterface is a security risk, and requires proper access rights.
  2. changing files causes the extra data present in the jpegs put there by photocameras to be discarded
  3. changing files potentially causes deterioration of the quality of the jpegs
  4. changing files has sometimes caused the file to be damaged in some way
  5. changing files makes it impossible to determine if the photo is already present in your collection

Technical

Some of the (new) stuff that is being used.
  1. JDK7 (Look for "JDK7" in the sourcecode)
    1. multiple catch
    2. try-with-resources
    3. new switch statement
    4. diamond-notation
    5. filevisitor interface
    6. Path class usage
  2. EJB 3.1
    1. no local interfaces on beans
    2. EJBs inside the WAR, no longer is an EAR required
    3. Improved Context and Dependency Injection
  3. Netbeans IDE 7.0.1.
  4. GlassFish Server Open Source Edition 3.1.1 (build 12).
  5. JPA (Hibernate)
  6. REST (Jersey)
  7. MySQL
  8. JQuery
  9. HTML, CSS, JavaScript and AJAX
  10. JSON

Database Schema

The database schema below shows the used Hibernate Entities. They have the same name as the tables. The database script below should run without errors on your average MySQL database.
drop table if exists Log;
drop table if exists Tag;
drop table if exists Comment;
drop table if exists GalleryPhotograph;
drop table if exists Gallery;   
drop table if exists Photograph;
drop table if exists Location;

create table Location (
 id bigint not null auto_increment primary key,
 filepath varchar(512)
);

create table Photograph (
 id bigint not null auto_increment primary key,
 location_id bigint not null,
 filename varchar(255),
 relativepath varchar(1024),
 taken timestamp,
 hashstring varchar(1024),
 filesize bigint,
 angle int,
 foreign key (location_id) references Location (id)
);

create table Gallery (
 id bigint not null auto_increment primary key,
 name varchar(80),
 description text,
 creation_date timestamp not null default current_timestamp,
 parent_id bigint,
 highlight bigint,
 sortorder int not null,
 foreign key (parent_id) references Gallery (id),
 foreign key (highlight) references Photograph (id)
);

create table GalleryPhotograph (
 id bigint not null auto_increment primary key,
 gallery_id bigint not null,
 photograph_id bigint not null,
 name varchar(255),
 description text,
 sortorder bigint,
 foreign key (gallery_id) references Gallery (id),
 foreign key (photograph_id) references Photograph (id)
);

create table Comment (
 id bigint not null auto_increment primary key,
 galleryphotograph_id bigint not null,
 author varchar(255),
 submitted timestamp,
 comment text,
 foreign key (galleryphotograph_id) references GalleryPhotograph (id)
);

create table Tag (
 tagname varchar(80) not null,
 photograph_id bigint not null,
 primary key (tagname, photograph_id),
 foreign key (photograph_id) references Photograph (id)
);

create table Log (
 id bigint not null auto_increment primary key,
 jobdate timestamp not null default current_timestamp,
 joblog blob not null
);

-- only allows a photograph to appear once in a gallery
create unique index unique_per_photograph_per_gallery
on GalleryPhotograph (gallery_id, photograph_id);

Update 1: Moved angle field from GalleryPhotograph over to Photograph
Update 2: It's nice to have a script for creating the database, but an ORM can automatically generate the proper tables for you if you like.

Saturday, 11 February 2012

PlantUML and NetBeans

If you're looking to integrate PlantUML with Netbeans with Maven, check out my blogpost here.

Introduction


One of the problems with software designers is that they do not enjoy writing Documentation. I do, but then again, I'm weird.

Now Documentation in the area of Java can be split up into two categories:
  • Javadoc comments, that reside in the Java source code, right where it matters
  • Specs, design documents, etc. which are made when the system is first designed and are then stored on a network drive or (if you're lucky) a version control system. They are never updated, become outdated, and forgotten but are sometimes used to provide new junior designers with a wrong idea of the architecture.
So, ideally, you'd wish to have all the specs on hand in the same fashion as your javadoc, with the hope that any change in the code by dilligent designers is also propagated in the javadoc.6

This is where I find PlantUML1 to be extremely handy.

Installing PlantUML in Netbeans


The following task addition lifted straight from the pages of PlantUML and added to build.xml in the netbeans project.
<!-- task definition -->
<taskdef name="plantuml"
  classname="net.sourceforge.plantuml.ant.PlantUmlTask"
  classpath="plantuml.jar" />


<!-- process ./src files -->
<target depends="javadoc-build" name="build-uml">
    <mkdir dir="${dist.javadoc.dir}/images"/>
    <!-- there is an issue where relative paths do not work -->
    <plantuml output="/home/mrbear/NetBeansProjects/YourProject/${dist.javadoc.dir}/images/" verbose="true">
        <fileset dir="./src">
            <include name="**/*.java" />
            <exclude name="**/*Test.java" />
        </fileset>
    </plantuml>
</target>
This won't work, as plantuml.jar cannot be found automatically. Once you've downloaded it you can let your project know where it is. A good explanation of this can be found at [3].

Running PlantUML and Javadoc


First of all, we add the uml syntax2 to the javadoc comments.
/**
 *
 * <p>Indicates the different sizes that are possible in the displaying
 * of pictures. BIG being un-scaled.</p>
 * <img src="../../images/ImageSize.png"/>
 * @author maartenl
 *
 * @startuml
 * "java.lang.Enum<ImageSize>" <|-- enum ImageSize
 * ImageSize : +ImageSize BIG
 * ImageSize : +ImageSize LARGE
 * ImageSize : +ImageSize MEDIUM
 * ImageSize : +ImageSize THUMB
 * ImageSize : +getHeight()
 * ImageSize : +getWidth()
 * @enduml
 */

public enum ImageSize
{

Build the "build-uml" target. It will automatically generate all the javadocs and start off generating uml diagrams. You can do this in the Files explorer in netbeans, right-click on build.xml on toplevel and select the appropriate run target. When the "build-uml" ant target is started in netbeans, the following output is shown:

main:
Starting PlantUML
Nb images generated: 1
BUILD SUCCESSFUL (total time: 0 seconds)

The webpage will look like the image below![5] VoilĂ , uml diagrams!

Issues

- Two files have the same name, so they both create the same named image file. And they get copied in the ant task, so only one of them remains!

The easiest solution is to add a filename after the "@startuml" command, to indicate the name of the image. This is especially important if you have two or more diagrams within the same Java file. I found it especially convenient when dealing with UML diagrams in package-info.java files.

A better solution would be to update the Ant task to take care of this automatically.

- I'm getting "taskdef class net.sourceforge.plantuml.ant.PlantUmlTask cannot be found using the classloader AntClassLoader[]"!

Make sure the plantuml.jar file is reachable in the classpath.

- Auto formatting in Netbeans of my Java source code throws my carefully created UML specs in the Javadoc into disarray!

Yes, while Eclipse has a /* @formatter:on */ editor annotation, I have been unable to find the same in Netbeans.

For now, the only solution I have found it to turn on 'explicit newlines' in formatting of the javadoc comments. You can do this by going in Netbeans to Tools->Options->Editor->Formatting->select Java->Category Comments and turn on "Preserve New Lines".

- The image shows errors, something like the image below.
Dot Executable: /usr/bin/dot
File does not exist
Cannot find Graphviz. You should try

@startuml
testdot
@enduml

or

java -jar plantuml.jar -testdot

It means you haven't installed the graphviz4 package that takes care of a lot of rendering.

root@localhost:~# apt-get install graphviz
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libcgraph5 libgvpr1
Suggested packages:
  graphviz-doc
The following NEW packages will be installed:
  graphviz libcgraph5 libgvpr1
0 upgraded, 3 newly installed, 0 to remove and 197 not upgraded.
Need to get 553 kB of archives.
After this operation, 1,741 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://nl.archive.ubuntu.com/ubuntu/ natty/main libcgraph5 i386 2.26.3-5ubuntu1 [47.8 kB]
Get:2 http://nl.archive.ubuntu.com/ubuntu/ natty/main libgvpr1 i386 2.26.3-5ubuntu1 [198 kB]
Get:3 http://nl.archive.ubuntu.com/ubuntu/ natty/main graphviz i386 2.26.3-5ubuntu1 [307 kB]
Fetched 553 kB in 0s (563 kB/s) 
Selecting previously deselected package libcgraph5.
(Reading database ... 163396 files and directories currently installed.)
Unpacking libcgraph5 (from .../libcgraph5_2.26.3-5ubuntu1_i386.deb) ...
Selecting previously deselected package libgvpr1.
Unpacking libgvpr1 (from .../libgvpr1_2.26.3-5ubuntu1_i386.deb) ...
Selecting previously deselected package graphviz.
Unpacking graphviz (from .../graphviz_2.26.3-5ubuntu1_i386.deb) ...
Processing triggers for man-db ...
Setting up libcgraph5 (2.26.3-5ubuntu1) ...
Setting up libgvpr1 (2.26.3-5ubuntu1) ...
Setting up graphviz (2.26.3-5ubuntu1) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
Thank the Heavens that I'm still running an old Ubuntu, that downloads the proper (read: old) version of GraphViz. PlantUML, I hear, has issues with the new and improved GraphViz 2.28. 1 2

Unfortunately, I was unable to use a relative path in the output attribute in the build.xml. I hope I can fix this later.

Update: changed ImageSizeEnum to ImageSize. Naming should not contain data type names, according to uncle Bob.

Second Update
: PlantUML according to this now works with the newest Graphviz version.

Third Update: Updated NetBeans javadoc formatting problem with a better solution.

References

[1] PlantUML
http://plantuml.sourceforge.net/
[2] Drawing UML with PlantUML - Language Reference Guide (Version 5737)
http://sourceforge.net/projects/plantuml/files/PlantUML%20Language%20Reference%20Guide.pdf/download
[3] NetbeansFAQ
http://wiki.netbeans.org/FaqAntJunitJar
[4] Graphviz
http://www.graphviz.org/
[5] Example
http://maartenl.github.com/YourPersonalPhotographOrganiser/javadoc/gallery/enums/ImageSize.html
[6] "To keep documentation maintained, it is crucial that it be incorporated in the source program, rather than kept as a separate document ... even high-level language syntax does not at all convey purpose." [DRY principle]
The Mythical Man-Month (Frederick P. Brooks, Jr.)

Wednesday, 14 December 2011

Netbeans Tips & Tricks

Contents

Netbeans 7.0.1. doesn't validate jdk 7.0 syntax in editor

Netbeans 7.0.1. doesn't start

How to automatically use a License in your new java files

Changing indentation style


Netbeans 7.0.1. doesn't validate jdk 7.0 syntax in editor

For example, editor complains about: "try-with-resources is not supported in -source 1.6 (use -source 7 or higher to enable try-with-resources)" in a try-with-resources block.

Right click project. Properties. Sources. Source-binary->jdk7. No problems after that.

Of course, there's still the problem that the new syntax in the JSP pages doesn't work.

Jk7 doesn't work with jsp pages yet, see http://java.net/jira/browse/GLASSFISH-17429 .


Netbeans 7.0.1. doesn't start

I just downloaded Netbeans 7.0.1 from http://www.oracle.com/technetwork/java/javase/downloads.

It didn't work.

No output on the console, either.

However, I was able to run Netbeans correctly from the root account.

It turns out that I had the settings of a previous version of Netbeans in my homedir. To wit:

  • .netbeans/
  • .netbeans-derby/
  • .netbeans-registration/

After removing said settings, netbeans started properly and created the setting directory .netbeans.

Hope it helps someone.


How to automatically use a License in your new java files

Add project.license=gpl30 (for example) to your project.properties file in nbproject directory of your project.


But there are easier ways to do it in Netbeans 7.4. Choose Project properties, select "License Headers" and just set the Global license to for example General Public License 3.0

Changing indentation style

To change editor settings.

Click the Tools > Options menu item.

In the icon display, click Editor.

In the right panel, select the category "Tabs and Indents" tab.

If it isn't already done, set the following:

Statement continuation Indent: 8

Number of Spaces per Indent: 4

Check Expand Tabs to Spaces.

In the right panel, select the category "Braces" tab.

If you like the Allman indentation style (like me), check the "New Line" for a Class declaration, Method declaration and Other.

References

NetBeans IDE
http://leepoint.net/notes-java/tools/netbeans/netbeans.html
Project-Level License Settings in NetBeans IDE 6.0
http://blogs.oracle.com/geertjan/entry/project_level_license_settings_in

Saturday, 1 October 2011

Creating Hello World in Netbeans IDE 7.0.1 and Glassfish 3.1

A simple attempt of mine to create a HelloWorld Enterprise JavaBean (EJB) in Netbeans 7.0.1. and Glassfish 3.1.

Primary use is for me to remember how to do this, and what needs to be configured to make it work.

Creating the JEE Application

First, start up your brand new Netbeans 7.0.1. and select a new project.

Select Java Enterprise Applications.





It will start creating the new project. You will end up with three new projects.


First of the projects, HelloWorldEE is the EAR file, which is a jar-file that is to be deployed to the glassfish server. It consists of two jar-files, that are created by the other two projects.

Second is HelloWorldEE-ejb, the project that is to contain our new Enterprise Java Beans (EJB).

Third is HelloWorldEE-war, the project that is to contain all the web stuff, like jsp pages, servlets, and what have you.

Let's create our first Enterprise Java Bean.



Here I've selected a Local interface for now. You'll notice two java files are generated, one containing the local interface and one containing the implementation.

We will add a business method.




Change the helloWorld method to return the string "Hello, world.". Now, in order to test it, we are going to create a java client that connects to the bean using Corba. However, for this to work, the interfaces need to be Remote, and not Local. Change the source code accordingly.

Your source code should look something like this:

package mrbear.beans;

import javax.ejb.Remote;

/**
 * The remote interface to my bean.
 * @author Mr. Bear
 */

@Remote
public interface MyFirstBeanRemote {

    /**
     * Returns the string "Hello, world."
     * @return String with text.
     */

    public String helloWorld();
    
}
package mrbear.beans;

import javax.ejb.Stateless;

/**
 * My first enterprise java bean.
 * @author Mr. Bear
 */

@Stateless
public class MyFirstBean implements MyFirstBeanRemote {

    @Override
    public String helloWorld() {
        return "Hello, world.";
    }

}

In the war project, a jsp page is automatically generated upon creation of the project, and it will help to check if the ear file was successfully deployed.

Try and "run" the project HelloWorldEE. A GlassFish 3.1 server will be started by Netbeans, the ear file deployed, and a webpage will be visible at url http://localhost:8080/HelloWorldEE-war/. It should show "Hello world!". Now, make no mistake! This is not our bean! This is the jsp page that is generated automatically in the war project. It shows that at least the ear file was successfully deployed.

The jsp file can be found at HelloWorldEE/HelloWorldEE-war/web/index.jsp

In your output window (HelloWorldEE(run)), you should see something like this:

Starting GlassFish Server 3.x
GlassFish Server 3.x is running.
Initial deploying HelloWorldEE to /home/mrbear/NetBeansProjects/HelloWorldEE/dist/gfdeploy/HelloWorldEE
Completed initial distribution of HelloWorldEE
Initializing...
Browsing: http://localhost:8080/HelloWorldEE-war

In the GlassFish log, you should see something like this:

INFO: Portable JNDI names for EJB MyFirstBean : [java:global/HelloWorldEE/HelloWorldEE-ejb/MyFirstBean, java:global/HelloWorldEE/HelloWorldEE-ejb/MyFirstBean!mrbear.beans.MyFirstBeanRemote]
INFO: WEB0671: Loading application [HelloWorldEE#HelloWorldEE-war.war] at [HelloWorldEE-war]
INFO: HelloWorldEE was successfully deployed in 5,409 milliseconds.

Pay special attention to the JNDI names used for the EJB MyFirstBean. We'll need those to create our HelloWorld java client.

Your bean should now be alive and kicking! You can check this by browsing to the administration console of your Glassfish server at http://localhost:4848/.


Creating the Java Client

Time to create a new project. Create a new project, and select Enterprise Application Client.





You do need to add a dependency in the HelloWorldClient to the HelloWorldEE-ejb (which resides in the HelloWorldEE) by selecting "add Project" in the Compile tab of "Libraries" of the Helloworld java client project.


Your java client source code in the main method should look something like this:

package helloworldclient;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import mrbear.beans.MyFirstBeanRemote;

/**
 * The client for connecting to the MyFirstBean bean.
 * @author Mr. Bear
 */

public class Main {

    /**
     * Main method, called when executing this program.
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        System.out.println("Starting...");

        System.out.println("Establishing connection to the bean...");
        MyFirstBeanRemote example;
        try {
            InitialContext initialContext = new InitialContext();

            // INFO: Portable JNDI names for EJB MyFirstBean : 
            // java:global/HelloWorldEE/HelloWorldEE-ejb/MyFirstBean
            example = (MyFirstBeanRemote) initialContext.lookup("java:global/HelloWorldEE/HelloWorldEE-ejb/MyFirstBean");
            System.out.println("Calling method on the bean...");
            System.out.println("     Result: " + example.helloWorld());
        } catch (NamingException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
        System.out.println("Exiting...");

    }

}

When executing said project (remember, the Glassfish is still running), you can see the following in the log of Glassfish:

INFO: ACDEPL103: Java Web Start services started for the app client HelloWorldClient (contextRoot: /HelloWorldClient)
INFO: HelloWorldClient was successfully deployed in 85 milliseconds.

And the log of your java client, should show the following indicating success:

Copying 1 file to /home/mrbear/NetBeansProjects/HelloWorldClient/dist
Copying 2 files to /home/mrbear/NetBeansProjects/HelloWorldClient/dist/HelloWorldClientClient
Warning: /home/mrbear/NetBeansProjects/HelloWorldClient/dist/gfdeploy/HelloWorldClient does not exist.
Starting...
Establishing connection to the bean...
Calling method on the bean...
Result: Hello, world.
Exiting...

Now this is just the basics, but it is always good to start from a simple example that works, and then branch out from there. Good luck!

I plan to keep this article updated with new versions of software that are issued, and with new expansions, like adding an ORM to your little bean.

Remarks

I've chosen for Netbeans 7.0.1, as there is an issue with automatic downloading of Glassfish 3.1 in Netbeans 6.9

In order for the java client to connect to the Glassfish when the Glassfish is not conveniently started by the Netbeans on your local machine, you need to change the settings used to connect to the remote host. This can be done programmatically using a Properties java hashmap thing, or you can use the dreaded jndi.properties file. I guess that last one could use a blog entry all on its own. [1]

I've not mentioned anything about setting up Glassfish on your local machine, as Netbeans basically does all that for you. You just need to select the little checkbox with "Download Glassfish" when creating a new Java EE Application Project.

It is a pleasure to work with Netbeans and Glassfish, basically because the two are nicely intertwined and setting up the environment is almost a point-and-click experience and speedily done. It makes it possible to spend more time developing and less time battling frameworks, fixing dependencies and installing jar-files.


Update


Ever since the coming of EJB 3.1, it is no longer necessary to have a WAR archive for your web related things, a JAR archive for your Enterprise Java Beans, and an EAR archive containing these two. If you are not interested in keeping these two strictly apart (in the name of modularization), you can just toss all your EJBs into the same WAR and deploy that WAR in EJB 3.1.

It simplifies life tremendously.

References


[1] How do I access a Remote EJB component from a stand-alone java client?
http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB