November 13, 2012

Best Practice Apache Wicket

There are some guidelines written about the best way how to use Apache Wicket, but I think I might have some more to contribute to all the things that has already been written.

1. And maybe the most important is always use Wicket Models.

First Wicket is a component based framework, which in itself implies you should always use Wicket Models.

Secondly wicket is also a framework that out of the box handles the back button dilemma, which is what should happen when the user press the back button in the web browser? Wicket handles this by versioning every page. Which means that if a user have in entered some data in a HTML form, then submitted and thereafter presses back button, Wicket will then out of the box present the values the way it was before pressing submit AND keeping you server Model in synch. You can get a good feeling of the above by playing around with the form example at http://www.wicket-library.com/wicket-examples/forminput/.

To achieve this Wicket uses the HTTP Session to store the previously pages states. To not now blow the RAM space on the server, you should almost always use the LoadableDetachableModel.

Be sure you have completely have understood the antipatterns at https://cwiki.apache.org/WICKET/best-practices-and-gotchas.html#BestPracticesandGotchas-Antipatterns.

The second and maybe finally most important Model is the CompoundPropertyModel. And remember that you can wrap Model. Example of that is:
class PersonList extends ListView<Person> {

    private static final long serialVersionUID = 1L;

    public PersonList(final String id, final IModel<List<Person>> model) {
        super(id, model);
    }

    @Override
    protected void populateItem(final ListItem<Person> item) {
        item.setModel(new CompoundPropertyModel<Person>(item.getModel()));
        item.add(new Label("id"));
        item.add(new Label("name"));
        // ...
    }
}

2. To keep wicket code more readable, avoid using anonymous inner classes.

Wicket as well as Swing code can blow up in your face when it comes to anonymous inner classes. Instead write separate classes in the same WebPage class, like the above example. Which result in in a much more cleaner code.
public class PersonPage extends WebPage {

    private static final long serialVersionUID = 1L;

    public PersonPage(final PageParameters parameters) {
        super(parameters);
        IModel<List<Person>> persons = ...;
        add(new PersonList("personList", persons));
    }
}

3. Try to only use the PageParameters constructor

Example of that you can see in the above PersonPage example. The reason for that is now you page can always be bookmarkable. Which the default constructor also can be, but it is more generic to directly use the PageParameters constructor, in case you later need to use a page parameters.

 

4. Do not try to reinvent the wheel when it comes to graphical components.

Wicket comes with a rich set of ready to use graphical components. Be sure to import them in your pom file.
<dependency>
    <groupid>org.apache.wicket</groupId>
    <artifactid>wicket-core</artifactId>
    <version>${wicket.version}</version>
</dependency>

<dependency>
    <groupid>org.apache.wicket</groupId>
    <artifactid>wicket-extensions</artifactId>
    <version>${wicket.version}</version>
</dependency>

<dependency>
    <groupid>org.apache.wicket</groupId>
    <artifactid>wicket-datetime</artifactId>
    <version>${wicket.version}</version>
</dependency>

If you need more have a look at http://wicket.visural.net/examples/, which have a nice WYSIWYG editor and a spinner.
Also since Wicket 6 is jQuery the backend library for Ajax. Look for example at the jQuery modal window at http://www.wicket-library.com/wicket-examples/ajax/modal-window.

 

5. Use Wicket XHTML namespace

See https://cwiki.apache.org/WICKET/wickets-xhtml-tags.html

 

6. Be sure you have configured Maven Jetty Plugin to restart whenever you have made code changes

<plugin>
    <groupid>org.mortbay.jetty</groupId>
    <artifactid>jetty-maven-plugin</artifactId>
    <version>${jetty.version}</version>
    <configuration>
        <scanintervalseconds>1</scanIntervalSeconds>
        <usetestclasspath>true</useTestClasspath>
        <connectors>
            <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <port>8080</port>
                <maxidletime>3600000</maxIdleTime>
            </connector>
        </connectors>
    </configuration>
</plugin>

7. And remember you can always debug your Wicket code with a JUnit.

Wicket has a great support for module testing support. But these test cases can also be used for debugging. When generating a Wicket project with the archetype you get a single JUnit test case with that you can start Jetty and then simply add breakpoints and you can debug your code.

References:

September 19, 2012

How to add Bookmark/Shortcut to Left Sidebar of Nautilus Manager in Ubuntu 12.04

1. First open the folder you want to bookmark.


 
2. Then press Ctrl+D. Now will a new bookmark be created in the upper left corner of nautilus manager.


September 2, 2012

Configure DatabaseServerLoginModule with Hashed Password on JBoss 7 AS

In this blog I will show you how to install org.jboss.security.auth.spi.DatabaseServerLoginModule in JBoss 7 AS and store the password in hashed format. The advantage of storing the password in hashed form is that a DB admin can not read the user's password in clear text. Which add a great security value.

Before we begin our tour we need to first install a database driver. In my previous blog I showed you how to install MySQL driver, please see http://magnus-k-karlsson.blogspot.se/2012/08/how-to-install-mysql-datasource-on.html. And in this blog I will continue to use MySQL for my data source. We will also use JBoss in standalone mode, since we are dealing with a single node installation. Remember to look at the new JBoss module capabilities if you are facing a multi node installation and you want to share the same configurations.

After you have installed your data source you can check your configuration by starting JBoss and you should receive something like in your JBoss server log.

Bound data source [java:jboss/datasources/MySQLDS]

Now continue by creating database schema and tables:
CREATE TABLE Users(username VARCHAR(255), passwd VARCHAR(255), PRIMARY KEY (username));
CREATE TABLE UserRoles(username VARCHAR(255), userRoles VARCHAR(255));
Now we continue with add a new security domain, i.e. actually configure our database login module
<security-domain name="StaticUserPwd" cache-type="default">
    <authentication>
        <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
            <module-option name="dsJndiName" value="java:jboss/datasources/MySQLDS"/>
            <module-option name="principalsQuery" value="select passwd from Users where username=?"/>
            <module-option name="rolesQuery" value="select userRoles, 'Roles' from UserRoles where username=?"/>
            <module-option name="hashAlgorithm" value="SHA1"/>
            <module-option name="hashEncoding" value="BASE64"/>
            <module-option name="hashCharset" value="UTF-8"/>
            <module-option name="hashUserPassword" value="true"/>
            <module-option name="hashStorePassword" value="false"/>
        </login-module>
    </authentication>
</security-domain>
Now we need a web application. I did not bother to build a maven application for that so I simply created a new folders manually
$ mkdir -p $JBOSS_HOME/standalone/deployments/msc-secure-webapp.war/WEB-INF
A simple Index.jsp page
$ touch $JBOSS_HOME/standalone/deployments/msc-secure-webapp.war/Index.jsp
<html>
<head>
</head>
<body>
    <h2>Hello <%= request.getRemoteUser() %></h2>
</body>
</html>
And the standard web application deployment descriptor:
$ touch $JBOSS_HOME/standalone/deployments/msc-secure-webapp.war/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 version="3.0">

 <display-name>MSC Secure Webapp</display-name>

 <welcome-file-list>
  <welcome-file>./Index.jsp</welcome-file>
 </welcome-file-list>

 <security-constraint>
  <web-resource-collection>
   <web-resource-name>Secure Webapp</web-resource-name>
   <url-pattern>/*</url-pattern>
   <http-method>GET</http-method>
   <http-method>POST</http-method>
   <http-method>PUT</http-method>
   <http-method>DELETE</http-method>
   <http-method>HEAD</http-method>
  </web-resource-collection>

  <auth-constraint>
   <description>These are the roles who have access.</description>
   <role-name>*</role-name>
  </auth-constraint>

  <user-data-constraint>
   <description>This is how the user data must be transmitted.</description>
   <transport-guarantee>NONE</transport-guarantee>
  </user-data-constraint>
 </security-constraint>

 <login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>StaticUserPwd</realm-name>
 </login-config>

 <security-role>
  <description>These are the roles who have access.</description>
  <role-name>*</role-name>
 </security-role>
</web-app>
And the corresponding JBoss application deployment descriptor:
$ touch $JBOSS_HOME/standalone/deployments/msc-secure-webapp.war/WEB-INF/jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <security-domain>java:/jaas/StaticUserPwd</security-domain>
</jboss-web>
Before we can fire up JBoss we need to tell the JBoss container to deploy the exploded web app.
$ touch $JBOSS_HOME/standalone/deployments/msc-secure-webapp.war.dodeploy
Now we can start JBoss and look for the deployment info log,

Deployed "msc-secure-webapp.war"

Now when we try to access the web application at http://localhost:8080/msc-secure-webapp we are meet by a username and password login window. Since we do not have any user in our database we will not be able to login yet.

Lets create some user. But how do we do that when the password are suppose to be stored in a hased format? Either you can write a small Java program to get the hashed password a easier way is to use openssl. To create a hashed password for admin simple enter
$ echo -n "admin" | openssl dgst -sha1 -binary | openssl base64
And with that hashed password we can create a new user with the followin sql insert.
Insert into Users values('admin','0DPiKuNIrrVmD8IUCuw1hQxNqZc=');
Insert into UserRoles values('admin','GRP_ADMIN');
Now you can open your web application http://localhost:8080/msc-secure-webapp/ and log in with username "admin" and password "admin".

August 16, 2012

Eclipse Keyboard Shortcut Does not Work on Ubuntu 12.04

When I installed Eclipse on Ubuntu 12.04 (or rather just unzipped the eclipse binary in my home folder and started the eclipse executable) some common Eclipse keyboard shortcut was not working, like Organize Import Ctrl+Shift+O or Inspect when debugging Ctrl+Shift+I. And the problem was that they were conflicting with the OS Ubuntu keyboard shortcut. To remove/edit the Ubuntu keyboard shortcut simply open Ubuntu Keyboard and walk through conflicting Eclipse keyboard short and either remove the Ubuntu keyboard shortcut or reassign them to other keyboard shortcut.

In the example below I simple removed the Ubuntu keyboard shortcut for Zoom in and Zoom out, since I don't need them.


August 15, 2012

How to Install Maven 3 on Ubuntu

So far there Maven 3 package is not yet available in the general Ubuntu repository, so you will have to do it manually. There are several way to do that, but I think the easiest way is to do it manually.

In short the installation follow:
$ cat /etc/environment
PATH="/home/magnus/bin/apache-maven-3.0.4/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_31
M2_HOME=/home/magnus/bin/apache-maven-3.0.4

August 13, 2012

How to install MySQL DataSource on JBoss EAP 6 and AS 7.

The interior of the JBoss EAP 6 and the community version JBoss AS 7, which EAP version is based on, has changed a lot in the latest version. In this blog I will walk you through how to install a MySQL DataSource, and by doing that I will touch two important differences with the new version of JBoss.
  • The changed classloading to a more OSGI like architecture.
  • The simplification of have only one configuration file.
First we will create a new module. A module in this sense is a package of classes that will be available to all our application through your JBoss node. This is a big differences compared with older JBoss version where all deployed archive where directly available to other deployed application when deployed in the deployment root folder.

You find module in $JBOSS_HOME/modules folder. To create a new module you need to do three things:
  1. Create a folder hierarchy for files.
  2. Copy module jar files.
  3. Create module configuration file – module.xml.
$ mkdir -p $JBOSS_HOME/modules/com/mysql/main
$ cp mysql-connector-java-5.1.19.jar $JBOSS_HOME/modules/com/mysql/mainmysql-connector-java-5.1.19.jar
$ touch $JBOSS_HOME/modules/com/mysql/main/module.xml
Now edit the module.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql">
    <resources>
        <resource-root path="mysql-connector-java-5.1.19.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
    </dependencies>
</module>
Now you are ready to use configure your DataSource. Here I will use the JBoss Standalone and not the Domain configuration. In short the main differences between Module and Standalone JBoss configuration is if you want to reuse your configuration through several JBoss instance you shoud use the Domain configuration approach. In this blog I will use the Standalone configuration, but the differences of doing the other way around is not big.

The configuration of the JBoss can be done in several way: 1. CLI 2. Web interface 3. or manually through editing xml file. Which way you choose is up to you, here I will show the result.

$JBOSS_HOME/standalone/configuration/standalone.xml:
        <subsystem xmlns="urn:jboss:domain:datasources:1.1">
            <datasources>
                ...
                <datasource jndi-name="java:jboss/datasources/YourProjectDS" pool-name="YourProjectDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:mysql://localhost:3306/YourProjectDB</connection-url>
                    <driver>mysql</driver>
                    <security>
                        <user-name>uid</user-name>
                        <password>pwd</password>
                    </security>
                </datasource>
                <drivers>
                    ...
                    <driver name="mysql" module="com.mysql"/>
                </drivers>
            </datasources>
        </subsystem>

August 1, 2012

Search JAR Files after Specific Class

Ones in a while I need to search in a lot of jar files after a specific class class and that is what this command:

$ find . -name "*.jar" -a -exec bash -c "unzip -l {} | grep Foo.class" \; -print