Categories
Java

velocity with custom loader

Velocity is a feature rich template engine for Java applications. This engine is mainly designed to have template files which then will be rendered into OutputStreams using a context. But you can also extend velocity to use in memory or database stored templates.

First you have to register your own ResourceLoader at the VelocityEngine:

final VelocityEngine ve = new VelocityEngine();
ve.setProperty("yamltemplates.resource.loader.class", YamlTemplateResourceLoader.class.getName());
ve.setProperty("yamltemplates.resource.loader.templatefile", templateFile);
ve.setProperty(VelocityEngine.RESOURCE_LOADER, "yamltemplates");
ve.setProperty(VelocityEngine.INPUT_ENCODING, "UTF-8");
ve.init();

Then you can implement your ResourceLoader:

public class YamlTemplateResourceLoader extends ResourceLoader {

    private Map<String, Object> templateData;

    @Override
    public void init(final ExtProperties configuration)
    {
        try
        {
            try (InputStream data = (InputStream) configuration.get("templatefile"))
            {
                Yaml yaml = new Yaml();
                templateData = yaml.load(data);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Reader getResourceReader(final String source, final String encoding) throws ResourceNotFoundException
    {
        try
        {
            if ("velocimacros.vtl".equals(source))
            {
                return buildReader(new ByteArrayInputStream(new byte[0]), encoding);
            }
            Object template = templateData.get(source);
            if (template == null)
            {
                throw new ResourceNotFoundException(source);
            }
            if (template instanceof String)
            {
                return new StringReader((String) template);
            }
            throw new RuntimeException("cannot handle " + template);
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean isSourceModified(final Resource resource)
    {
        return false;
    }

    @Override
    public long getLastModified(final Resource resource)
    {
        return 0;
    }
}

Last but not least you can render your templates like any other templates with Velocity:

StringWriter stringWriter = new StringWriter();
VelocityContext context = new VelocityContext();
context.put("myparam", "Hello World!");
contextSetup.setupContext(context);
ve.getTemplate(templateName).merge(context, stringWriter);
String result = stringWriter.toString();

}

Categories
Java

JPA / JQL + QueryDSL string replace

Sometimes you need a string replace in SQL query, for example to compare multiple values each other which need to manipulate before comparing.

Unfortunately JPA did not support any replace function, so you have to use database specific functions. You should read the documentation of your database server how you can replace strings via SQL. For PostgreSQL you can use the replace function.

To use custom functions with QueryDSL, you have to use templates as described in a previous blog post about difference of dates in JPA.

final StringTemplate convertedField1 = Expressions.stringTemplate("function('replace', {0}, '/', '-')", model.field1);

Then you can use this template in your query (for example compare replaced field1 with field2 of your model):

new JPAQuery<>()
…
.where(convertedField1.eq(model.field2))
Categories
Java

generate HTML MimeMessage with Java

If you want to send some emails with your Java application, you may also want to format these mails using HTML. To achieve this, you have to build a correct multipart message defined in RFC 2045 and RFC 2046 and some more.

The header information of an email, like recipient, subject, etc., differs not from plain text mails:

MimeMessage mimeMessage = new MimeMessage((Session) null);
mimeMessage.setFrom("foo@example.com");
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress("bar@example.com", "Mr. Bar"));
mimeMessage.setSubject("My Subject", "UTF-8");

You should use a common character encoding for subjects. UTF-8 is a recommended and public supported one. This also applies for message content.

Now create the message body:

//create multipart
MimeMultipart content = new MimeMultipart("alternative");
//create simple textpart; content-type text/plain
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("content which is displayed, if mail client did not support HTML mails", "UTF-8");
//adds text part to multipart
content.addBodyPart(textPart);
//create html textpart; content-type text/html
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setText("<html><body><p>My Mailtext</p></body></html>, "UTF-8", "html");
content.addBodyPart(htmlPart);
//set content of mail to be multipart
mimeMessage.setContent(content);
Categories
Java

class based JSR303 – validator adding error on property

Sometimes it is necessary to validate one property or multiple properties of a class at one time or in relation to each other, but you want to add a constraint violation to the specific property. The solution will described in this post

You have your model:

@ValidateFieldIfFlag
public class Model {
    @Id
    @GeneratedValue
    private int id;

    private boolean flag;

    private String field;

    ... // getter and setter following
}

As you see the class uses a custom validator ValidateFieldIfFlag to validate a Model instance.

So you have the annotation:

@Constraint(validatedBy = {ValidateFieldIfFlagValidator.class})
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface ValidateFieldIfFlagValidator
{
	String message() default "my error message";

	Class<?>[] groups() default {};

	Class<? extends Payload>[] payload() default {};
}

And your validator:

public class ValidateFieldIfFlagValidator implements ConstraintValidator<ValidateFieldIfFlagValidator, Model>
{
    public boolean isValid(Model model, ConstraintValidatorContext context) {
        if (!model.isFlag()) return true;
        //if flag is set, field should be nonEmpty      
        return model.getField() != null && !model.getField().isEmpty();
    }
}

The validator will validate the field to be non empty, if the flag is set. Unfortunately you will receive a ConstraintViolationException for the whole instance and not only for the field. To change this, you have to modify the validator:

public class ValidateFieldIfFlagValidator implements ConstraintValidator<ValidateFieldIfFlagValidator, Model>
{
    public boolean isValid(Model model, ConstraintValidatorContext context) {
        if (!model.isFlag()) return true;
        //if flag is set, field should be nonEmpty      
        if (model.getField() != null && !model.getField().isEmpty()) return true;
        ConstraintValidatorContext.ConstraintViolationBuilder constraintViolationBuilder = context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate());
        constraintViolationBuilder.addPropertyNode("field").addConstraintViolation();
        context.disableDefaultConstraintViolation();        
        return false;
    }
}

This suppress the default, class matched ConstraintViolationException, and creates a ConstraintViolationException matching the property “field”.

Categories
Java

calculate date difference in JPA / JPQL query using PostgreSQL and QueryDSL

Unfortunately JPA or JQL currently did not support a date difference function. So you have to use native database functions. In PostgreSQL you would use date_part like:

SELECT DATE_PART('day', date2 - date1) FROM mytable

JPA only supports to call functions with simple parameters, but not the calculation of two dates. So you have the problem to subtract one date or timestamp from another. I used a custom function to solve this problem:

CREATE OR REPLACE FUNCTION datediff(a TIMESTAMP, b TIMESTAMP) RETURNS integer AS $$
BEGIN
    RETURN DATE_PART('day', a - b);
END;
$$ LANGUAGE plpgsql

So you can use this function with two simple parameters.

But how to use this function in QueryDSL? This is quite easy. You just have to define a template, especially a number template in this example. You can use the static methods in class Expressions to create such templates. This template is then easily usable in the next query.

QMyTable myTable = QMyTable.myTable;
final NumberTemplate<Integer> template = Expressions.numberTemplate(Integer.class, "function('datediff', {0}, {1})", myTable.date1, myTable.date2);
JPAQuery<MyTable> query = new JPAQuery<>(getEntityManager()).select(myTable).from(myTable).where(template.goe(5));
return query.fetch();

Categories
Java

days between two dates with Java 8

A common task in programming is to calculate a difference between two dates / timestamps. Java 8 introduced a new Date/Time API for solving such problems in an easy way.

To use this API you have to use LocalDate or LocalTime. So if you have an “old school” java.util.Date instance, you must convert it..

LocalDate localDate = new Date().toInstant().atZone(ZoneId.systemDefault());

Now you can calculate the difference between two values:

//now
LocalDate localDate1 = LocalDate.now();
//a converted future date 
LocalDate localDate2 = dateInFuture.toInstant().atZone(ZoneId.systemDefault());
int differenceInDays = localDate1.until(localDate2, ChronoUnit.DAYS)

A second variant is to use ChronoUnit method between:

//now
LocalDate localDate1 = LocalDate.now();
//a converted future date 
LocalDate localDate2 = dateInFuture.toInstant().atZone(ZoneId.systemDefault());
int differenceInDays = ChronoUnit.DAYS.between(localDate1, localDate2)

Categories
GWT Java Maven

HTMLUnit and GWT

After developing on an other aspect of a project, I realized later that all my GWT testcases didn’t work anymore. I got the following strange Exception:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
java.lang.NoSuchFieldError: FIREFOX_17
	at com.google.gwt.junit.RunStyleHtmlUnit.<clinit>(RunStyleHtmlUnit.java:200)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at com.google.gwt.junit.JUnitShell.createRunStyle(JUnitShell.java:1181)
	at com.google.gwt.junit.JUnitShell.doStartup(JUnitShell.java:942)
	at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:982)
	at com.google.gwt.junit.JUnitShell.getUnitTestShell(JUnitShell.java:698)
	at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:672)
	at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:421)
	at junit.framework.TestCase.runBare(TestCase.java:141)
	at junit.framework.TestResult$1.protect(TestResult.java:122)
	at junit.framework.TestResult.runProtected(TestResult.java:142)
	at junit.framework.TestResult.run(TestResult.java:125)
	at junit.framework.TestCase.run(TestCase.java:129)
	at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:247)
	at junit.framework.TestSuite.runTest(TestSuite.java:255)
	at junit.framework.TestSuite.run(TestSuite.java:250)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
</clinit>

The exception also occurred via Maven and not only in IntelliJ, so I knew it has something to do with my Maven-Project.

After checking the dependencies of my project with mvn dependency:tree, I found a new transitive dependency of a new added dependency. Because I didn’t need the htmlunit-part of this component I excluded the htmlunit-dependency with the following directive in my pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencies>
....
    <dependency>
        <groupdid>my.dependency
        <artifactid>mydependency
        <exclusions>
            <exclusion>
                <groupid>net.sourceforge.htmlunit</groupid>
                <artifactid>htmlunit</artifactid>
            </exclusion>
        </exclusions>
    </artifactid></groupdid></dependency>
....
</dependencies>

A deeper analysis of the problem shows, that the transitive dependency was too new, because the field FIREFOX_17 is not available any more, but the newer one like FIREFOX_38.

Categories
GWT Java Javascript Maven

GWT-Hidden-Feature: code coverage

In July 2012 a until now rarely documented feature was added to GWT (related Git-Commit). It’s code coverage on the client side.

How it works

You can activate it via the System-Property “gwt.coverage”. The property-value must contain either all named Java source files separated by comma, or it must point to a text file containing all Java source files; one per line. Now the GWT compiler will instrument the corresponding JavaScript which is based on the named Java source files. Additionally the compiler registers an onUnLoad-Event, which stores the code coverage into LocalStorage of the browser.

Maven-Example

I have a simple GWT-Project which is build via Maven. In the main source (src/main/java/org/jajax/gwt/test/client/MyEntryPoint.java) I have the following file:

1
2
3
4
5
6
7
8
9
10
11
12
package org.jajax.gwt.test.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
 
public class MyEntryPoint implements EntryPoint {
 
   @Override
   public void onModuleLoad() {
       Window.alert("Hello world");
   }
}

Additionally I created a Textfile (target/gwt-coverage-sources.txt) with the following content:

1
org/jajax/gwt/test/client/MyEntryPoint.java

Now only the configuration of GWT is missing. You have to add the Parameter gwt.coverage=target/gwt-coverage-sources.txt.

1
2
3
4
5
6
7
8
<plugin>
    <groupid>org.codehaus.mojo</groupid>
    <artifactid>gwt-maven-plugin</artifactid>
    <version>2.7.0</version>
    <configuration>
        <extrajvmargs>-Dgwt.coverage=target/gwt-coverage-sources.txt</extrajvmargs>
    </configuration>
</plugin>

Now if you run you application, you can access the code coverage via JavaScript

?View Code JAVASCRIPT
1
localStorge.getItem("gwt_coverage");

You will get a JSON with the following content:

1
{"org/jajax/gwt/test/client/MyEntryPoint.java":{"6":1,"10":1}}

The inner object has for every line as key a value of 0 for a missing coverage or 1 for covered code.

Conclusion

This feature is very interesting, because the alternatives are very rare. The old option to use Emma / Jacoco is not functional anymore with the current versions of Java (1.8), GWT (2.7.0 / 2.8.0-SNAPSHOT), etc. So this feature seems to be a good alternative. Unfortunately there is no tool to extract the code coverage of Unit-Tests or Integration-Tests, but I will release a Tool, which connects the GWT code coverage with Jacoco Reports. So stay tuned!

Categories
GWT Polymer/Webcomponents

Resources for Quickstart with GWT and Polymer

Today I would like to give some resources for a quick start in development with GWT and Polymer components. Polymer components are an implementation of basic components with the Webcomponents technology.

  1. The first point is an overview of the Polymer components in GWT. So you have an overview what is possible. You can click through the show case of the gwt-polymer-elements library.
  2. The second point is the official documentation from the GWT-Project. This is a good start to see how you will consume webcomponents with GWT.
  3. As described there you will use the gwt-polymer-elements library from vaadin. This library provides standard polymer (paper and iron elements and some vaadin elements) ready for use with GWT. Currently the Version 1.2.3.0 is the latest release and you will need to use the 2.8.0-SNAPSHOT version of the GWT project.

With these resources and the provided demos you will be able to start your development and play a little bit with the technologies. In the next days I will write some more Howtos about concerning points. If you have some problems with the setup, feel free to write a comment.

Categories
Java

Client-Certificate Exception “Cannot recover key”

Today I tried to use a SSL with a Client-Certficate. I used the keytool to create a keystore and imported a PKCS12 – Certifcate with:

1
keytool -v -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -destkeystore mykeystore -deststoretype JKS

After using it with Java I got the following error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(KeyProtector.java:311)
at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:121)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:38)
at java.security.KeyStore.getKey(KeyStore.java:763)
at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.&lt;init&gt;(SunX509KeyManagerImpl.java:113)
at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:48)
at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:239)
at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.getDefaultKeyManager(DefaultSSLContextImpl.java:170)
at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.&lt;init&gt;(DefaultSSLContextImpl.java:40)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:357)
at java.lang.Class.newInstance(Class.java:310)
at java.security.Provider$Service.newInstance(Provider.java:1221)
... 21 more

The solution here is to correct the password of the Java-Keystore. The password of the P12-Certifcate and the password of the Keystore has to be the same.