Friday, October 14, 2016

Processing custom object from html form data of JSON from a POST request with JAX-RS

The main concept is, that if your Java bean class implements the Serializable interface than JAX-RS supports conversion from and to JSON out of the box.
So I would expect something like this to work:
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) // this is the "application/x-www-form-urlencoded" media type.
public void processFeedback(@FormParam("feedback") Feedback feedback) {
 this.feedback = feedback;
}
However, with @FormParam this does not seem to work for me.
I get this error:
Caused by: java.lang.RuntimeException: RESTEASY003875: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.FormParam("feedback") on public void my.app.FeedbackEndpoint.processFeedback(my.app.Feedback) for basetype: my.app.Feedback
The solution is to do implement one of the required ways of instantiating the class, so
  • a constructor that takes a String parameter, or
  • a static valueOf() method, or
  • a static fromString() method

Monday, September 26, 2016

Mercurial Hg - frequently used commands

hg clone
copy a locally non-existent repository from remote repository
hg pull --rebase
pull changes from remote to local, rebase local commits on new head
hg pull -u
pull changes from remote to local, update working dir to new head
hg update [optionally: where]
updates working dir to head or specified revision
hg st
hg status
list status of the working directory
hg commit
commit changes
hg commit --amend
amend last commit
hg push
push to remote repository
hg rebase -s [what] -d [where]
rebase one commit and its children to another commit -- commits specified by [commit number]
hg strip --keep [what and its children]
remove a commit and its children, and keep the changes in the working directory
hg strip [what and its children]
delete a commit and its children (will not keep changes!)
hg purge
cleans the working directory
hg shelve
hg unshelve
shelve or unshelve changes in the working directory

Tuesday, September 20, 2016

Docker: frequently used commands

list all images:
docker images
list all containers:
docker ps -a
stop all running containers:
docker stop $(docker ps -a -q)
remove all containers:
docker rm $(docker ps -a -q)
force (-f) remove all running or non-running containers:
docker rm -f $(docker ps -a -q)
remove all images:
docker rmi $(docker images -q)
build docker image with the tag tutorial/webapp:latest from the path .:
docker build -t tutorial/webapp:latest .
download a docker image from the docker hub:
docker pull tutorial/webapp:latest
run the image tutorial/webapp with the specified --name, in the background (-d), exposing inner port 8080 on 80 (-p) and setting an environmental variable (-e):
docker run --name tutorial -d -p 80:8080 -e "ENV_VAR=env-var" tutorial/webapp
run bash console inside the container:
docker exec -it nameofthecontainer /bin/bash
build a docker image from a Dockerfile in the current directory:
docker build --tag my_image .

Thursday, June 2, 2016

Mocking void methods with Mockito in JUnit

Sources:

There are multiple ways to stub a void method with Mockito.
I chose to use doAnswer() because this way it will show up in the test coverage report (EclEmma in Eclipse) properly. When I used doThrow(), it did not appear as covered, because an exception was thrown.
As a brute-force approach, I used the System.out to verify that the method was called.
public class MyClassTest {
 private MyOtherClass mockMyOtherClass;
 private MyClass myClass;
 
 private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
 private final String successfulRunMessage = "Successful run";
 private Answer successfulRunAnswer = new Answer() {
  public Void answer(InvocationOnMock invocation) {
   System.out.println(successfulRunMessage);
   return null;
  }
 };

 @Before
 public void setUpStreams() {
  System.setOut(new PrintStream(outContent));
 }

 @After
 public void cleanUpStreams() {
  System.setOut(null);
 }

 @Before
 public void setUp() {
  mockMyOtherClass = Mockito.mock(MyOtherClass.class);
  myClass = new MyClass(mockMyOtherClass);
 }

 @Test
 public void testVoidMethodCall() {
  Mockito.doAnswer(successfulRunAnswer).when(mockMyOtherClass).myVoidMethod());
  myClass.runMyVoidMethod();
  assertEquals(successfulRunMessage, outContent.toString().trim());
 }
}


Tuesday, May 24, 2016

GIT: Accidentally amended a commit that was already pushed? Here's how to fix it.

git reset HEAD^ --mixed // delete the latest local commit, but keep the working directory
git stash save // stash away working directory changes
git pull // pull the remote commit that you originally amended
git stash apply // apply the stash on it
git add -u // stage the changes
git commit // commit the changes that you originally amended to a new commit

Friday, May 6, 2016

Run a Maven Vaadin application on an embedded Jetty server in Eclipse

Source: Embedding Jetty

Add Maven Dependencies

<properties>
 <jetty.version>9.3.0.v20150612</jetty.version>
</properties>

<dependencies>
<dependency>
 <groupId>org.eclipse.jetty</groupId>
 <artifactId>jetty-servlet</artifactId>
 <version>${jetty.version}</version>
</dependency>
<dependency>
 <groupId>org.eclipse.jetty</groupId>
 <artifactId>jetty-continuation</artifactId>
 <version>${jetty.version}</version>
</dependency>
<dependency>
 <groupId>org.eclipse.jetty</groupId>
 <artifactId>jetty-server</artifactId>
 <version>${jetty.version}</version>
</dependency>
</dependencies>

Create a Server

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.resource.PathResource;

public class VaadinApplicationServer 
{
    public static void main( String[] args ) throws Exception
    {
        Server server = new Server(8080);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        context.setBaseResource(new PathResource(new File("src/main/webapp")));
        context.addServlet(MyUIServlet.class, "/*");
        server.setHandler(context);
        server.start();
        server.join();
    }
}

Run as Java application

Now it is possible to run your Vaadin project as a Java application with the Jetty VaadinApplicationServer class.

Getting started with a Maven Vaadin project in Eclipse without the Eclipse Vaadin Plugin

Environment: Eclipse Luna for Java SE on Windows 10 with Apache Tomcat server and Maven

Install Eclipse software

  • either install Eclipse IDE for Java EE Developers, which has the needed dependencies by default,
  • or install the following software for the Eclipse IDE for Java Developers:
    • Eclipse Java EE Developer Tools
    • JST Server Adapters Extensions
The installation is done by the following procedure:
  • in Eclipse, navigate to Help -> Install New Software...
  • select Work with: --All Available Sites--
  • expand Web, XML, Java EE and OSGi Enterprise Development category menu
  • select the following:
    • Eclipse Java EE Developer Tools
    • (Eclipse Java Web Developer Tools)*
    • JST Server Adapters Extensions
    • (JST Server Adapters)*
    • (JST Server UI)*
  • click Next, click Next again, accept Licence agreement, click Finish to install.
As a result, you are able to add a Server runtime.
Try it: follow the tutorial in the Eclipse Help: Adding the Apache Tomcat runtimes
As a result, you now have the Java EE perspective for Eclipse.
As a result, the Run on Server option becomes available for projects.

*(might be needed to fix errors)

Add Maven Archetypes for Vaadin

Source: Set up a Vaadin project with Maven2

  • in Eclipse, navigate to Window -> Preferences
  • expand Maven menu item, select Archetypes
  • click Add Remote Catalog...
    • Catalog File: https://repo1.maven.org/maven2/archetype-catalog.xml
    • Description: Maven2
  • click OK.
As a result, when creating a new Maven project, the Vaadin archetypes became available.
Try it:
  • in Eclipse, go to File -> New -> Other... -> Maven -> Maven Project
  • leave the Create Simple Project checkbox unselected, click Next
  • Filter for Vaadin, select the com.vaadin archetype you would like to create, click Next
  • proceed with project creation.
Here is a description of the Archetypes: https://vaadin.com/maven#archetypes

Set up Facets for your project

In order for Eclipse to recognize your Vaadin project as a Web Project that can be deployed to a server, you need to do the following:
  • in Eclipse, navigate to your vaadin project's Properties (right click on project name in Project Explorer, select Properties)
  • select Project Facets
  • click Convert to faceted form...
  • leave the Java option selected
  • select the option Dynamic Web Module, set version to 3.1
    • click Further configuration availiable...
      • set Content directory to src/main/webapp (the default maven webcontent directory)
      • select Generate web.xml deployment descriptor and click OK.
As a result, you can deploy your project to the server.

Set up Project Deployment Assemblies

Add Maven repositories

In order for a the Maven dependencies to be deployed on the Server, you need to do the following:
  • in Eclipse, navigate to your vaadin project's Properties (right click on project name in Project Explorer, select Properties)
  • select Deployment Assembly
  • click Add...
    • select Java Build Path Entries, click Next
    • select Maven Dependencies, click Finish
  • click OK.
As a result, now your Vaadin web application should run on the server.

Ensure the rest is good

  • Source --> Deploy Path
  • /src/main/java --> WEB-INF/classes
  • /src/main/resources --> WEB-INF/classes
  • /src/main/webapp --> /

Build Vaadin plugin goals with Maven

In order for a Vaadin application to run, you first need to build the components.
The Plugin Goals can be found in the pom.xml: update-theme, update-widgetset, compile, compile-theme.
  • in Eclipse, go to Run-> Run Configurations...
  • right click on Maven Build select New
    • Name your configuration
    • Base directory is the project's directory
    • Goals have to be separated by space. Copy-paste in the following:
      • com.vaadin:vaadin-maven-plugin:update-theme com.vaadin:vaadin-maven-plugin:update-widgetset com.vaadin:vaadin-maven-plugin:compile com.vaadin:vaadin-maven-plugin:compile-theme
    • click Apply.
    • click Run to run the build. 

Thursday, April 28, 2016

Using Hibernate 5.0.1 with Vaadin 7

Sources:

Sources for the fixes: 
In Vaadin 7 the Application class was replaces with the UI class. Instead of configuring the web.xml, VaadinServlet can be used with the proper annotations.
Instead of transaction listeners, servlet filters can be used to intercept the request and manage the session.

The following is gpiercey's implementation that is updated for Hibernate 5.0.1

Interceptor

@WebFilter(urlPatterns = { "/*" }, dispatcherTypes = { DispatcherType.REQUEST, DispatcherType.FORWARD,
  DispatcherType.INCLUDE, DispatcherType.ERROR })
public class SessionInterceptor implements Filter
{
 private static final ApplicationLogger logger = new ApplicationLogger(SessionInterceptor.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException
 {
  logger.executionTrace();
 }

 @Override
 public void destroy()
 {
  logger.executionTrace();
  final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();

  if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
   session.getTransaction().commit();

  if (session.isOpen())
   session.close();
 }

 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
   ServletException
 {
  final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();

  try
  {
   if (session.getTransaction().getStatus() != TransactionStatus.ACTIVE)
    session.beginTransaction();

   chain.doFilter(request, response);

   if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
    session.getTransaction().commit();
  }
  catch (StaleObjectStateException e)
  {
   logger.error(e);

   if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
    session.getTransaction().rollback();

   throw e;
  }
  catch (Throwable e)
  {
   logger.error(e);

   if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
    session.getTransaction().rollback();

   throw new ServletException(e);
  }
 }
}

Database Util

public class DatabaseUtil
{
    private final static ApplicationLogger logger = new ApplicationLogger(DatabaseUtil.class);
    private final static SessionFactory sessionFactory;
    private final static String CONFIG = "/path/to/hibernate.cfg.xml";

    static
    {
        try
        {
            logger.trace("Initializing DatabaseUtil");
            
            /**
             * 
             */
            sessionFactory = new Configuration().configure(CONFIG).buildSessionFactory();
            
        }
        catch (Throwable e)
        {
            logger.error(e);
            throw new ExceptionInInitializerError(e);
        }
    }

    public static SessionFactory getSessionFactory()
    {
        logger.executionTrace();

        if (sessionFactory.getCurrentSession().getTransaction().getStatus() != TransactionStatus.ACTIVE)
            sessionFactory.getCurrentSession().beginTransaction();

        return sessionFactory;
    }
}

Hibernate Configuration

Current session context property has to be added to the Hibernate Configuration:
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>

Maven Dependencies

The following repository and dependencies were used:
<repository>
<id>vaadin-addons</id>
    <url>http://maven.vaadin.com/vaadin-addons</url>
</repository>

<dependency>
    <groupId>org.vaadin.addons</groupId>
    <artifactId>hbncontainer</artifactId>
    <version>2.0.1</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>

Usage

Now for database calls from the WebApp you can use the followings:
final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();
final Transaction transaction = session.getTransaction();

Exaple: UI and VaadinServlet class

@SuppressWarnings("serial")
@Theme("mytheme")
public class MyUI extends UI {

        @WebServlet(value = "/*", asyncSupported = true)
 @VaadinServletConfiguration(productionMode = false, ui = MyUI.class)
 public class MyServlet extends VaadinServlet {}

        @Override
 protected void init(VaadinRequest request) {

  final VerticalLayout layout = new VerticalLayout();
  layout.setMargin(true);
  setContent(layout);

  TextField message = new TextField();
  message.setCaption("Type your message here:");
  Button writeButton = new Button("Write to database");
  writeButton.addClickListener(new Button.ClickListener() {
   @Override
   public void buttonClick(ClickEvent event) {

    getNewSession().save(new Message(message.getValue()));

    layout.addComponent(new Label("Written to database."));
   }

  });

  Button readButton = new Button("Read from database");
  readButton.addClickListener(new Button.ClickListener() {
   @Override
   public void buttonClick(ClickEvent event) {

    List<Message> result = getNewSession().createQuery("from Message").list();
    for (Message msg : result) {
     layout.addComponent(new Label(msg.getId() + " " + msg.getText()));
    }

    layout.addComponent(new Label("Read from database."));
   }
  });

  layout.addComponents(message, writeButton, readButton);
 }

 private Session getNewSession() {
  return DatabaseUtil.getSessionFactory().getCurrentSession();
 }
}

Monday, April 25, 2016

Setting up H2 database connection in Eclipse Luna in a Maven project

Sources:

Download the H2 Database Engine

  • Open the pom.xml of your project >
  • add H2 database engine as a dependency.
For this tutorial version 1.4.191 was used.
Maven repository: http://mvnrepository.com/artifact/com.h2database/h2
To download it, right-click on the Project Name in Eclipse Project Explorer > Maven > Download Sources

Download Eclipse DTP (Data Tools Platform)

  • In Eclipse, go to Help > Eclipse Marketplace... > 
  • search Data Tools Platform > 
  • click Install > 
  • select both Extender SDK and Enablement Extender SDK > 
  • accept licence agreement > 
  • wait patiently until a popup informs you that the installation was successful and Eclipse needs to be restarted.

Open the "Database Development" perspective

This perspective was installed with the DTP.
  • In Eclipse, go to Window > Open Perspective > Other... > Database Development 

Add Database Connection

  • In the Database Development perspective, in the Data Source Explorere, right-click on Database Connections > New... >
  • select Generic JDBC and enter a Name for the connection then click Next >
  • select H2 Driver from the list of drivers.
  • if the list is empty, click New Driver Definition button >
    • on the Name/Type tab, click Generic JDBC Driver and give it a unique Driver Name.
    • on the JAR list tab, click Add JAR/Zip... > select H2 JAR file from Maven repository > click Open.
    • on the Properties tab, enter a Database Name for the database, and the following:
      • Connection URL - jdbc:h2:~/test
      • Driver Class - org.h2.Driver
      • User ID - sa
    • click OK.
  • click Test Connection to see that the connection works.
  • click Finish.
Now you can connect to the database by right-click on the name > Connect.
Once you connected you can edit the tables by right-click on the table name > Data > Edit

Connect to the Database

To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code:
import java.sql.*;
public class Test {
    public static void main(String[] a)
            throws Exception {
        Class.forName("org.h2.Driver");
        Connection conn = DriverManager.
            getConnection("jdbc:h2:~/test", "sa", "");
        // add application code here
        conn.close();
    }
}

Create a new Database

By default, H2 creates a new database on the first connection, if the one with the specified name does not exist.
After the  jdbc:h2: prefix a path to the database can be given. The ~/test creates a new test database in the user's home directory.

Friday, January 1, 2016

Idea Specification: The Notebook App

The Notebook App is a notebook app, that simulates the way I usually use a regular paper notebook.

User Stories:
  • Notebook identification
    • The user is able to create multiple notebooks. Each notebook has a unique identifier. The user is prompted to name the notebook for easier visual identification.
    • The user can add additional identification data to the notebook like a colour or a year/month or user created category.
  • Page content navigation
    • A notebook is a page collection, and is defined with a fix number of pages. This number is a default that the user can set.
    • The user can open up a notebook in different places:
      • beginning, 
      • end, 
      • last written page
      • next empty page
      • last viewed page
      • bookmarks
    • The default is that it opens at the last written page
  • Page layout and gestures
    • The notebook is by default the portrait size of the device screen. 
    • The user can turn the pages with the swipe gesture
  • Page reorganization
    • The user can add new pages to the notebook.
    • The user can reorganize the pages of the notebook.
    • The user can move or copy pages to a different notebook.
  • Data content types
    • The user can add text, drawings and pictures to the notebook.
    • The user can modify the default font properties of the text.
    • The user can underline, italics and bold text.
Requirements
  • The app should load fast 
  • It should be easy for the user to add new notes
  • It should be easy for the user to find notes
  • The user should be able to create backup copy of the notebooks
    • Export pdf, store in cloud, etc.