Opublikowany
Komentarze 0

Background

Many times, we encounter the need to store date and time in our database. Throughout application development, we need to make CRUD operations on that stored data. In my case, I use Spring Boot with Spring Data as a persistence layer. I’m still not sure whether the word “layer” is truly appropriate in modern development techniques, but nevertheless, we’ll say that Spring Data is my persistence layer.
As database I use Postgres which has quite nice features and what is most important it’s free.
Detailed technology stack looks like:
- PostgreSQL DB
- Spring Boot 1.5.3
- Spring Data JPA
- Lombok (since I do not like to write getters, setters and so on)
- Angular 2 on front end (but that is not important in this post)

Problem

The first problem that I encounter is JPA mapping types in my database. I have a Timestamp column type, which fits all my needs at the database level — it stores date and time with the appropriate time zones, so everything that I need is right there.
But, JPA (the Hibernate implementation in our case) implements a Postgres SQL timestamp as java.sql.Timestamp or java.sql.Date which is not what I want in my Spring Boot application. I mean, I could deal with ava.sql.* types but as of Java 8 we have LocalDate and LocalDateTime classes with that nice new features like plusDays methods.
Generally I would like to have new Time API in my application.
So this is what our database table looks like:
CREATE TABLE public.tableA (
	id int4 NOT NULL DEFAULT nextval('terminykursow_seq'::regclass),
	termA timestamp NULL,
	termB timestamp NULL,
	idother int4 NULL
);

And this is the corresponding entity:
@Entity
@Data
@Table(name = „tableA”, schema = „public”)
public class EntityA implements Serializable { @Id @SequenceGenerator(name=„tableA_seq”, sequenceName=„tableA_seq”, allocationSize=1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator=„tableA_seq”) private Integer id; private LocalDateTime terminod; private LocalDateTime termindo;

… other entity stuff … }

Solution


Without any changes, the code compiles and the application starts correctly… but there are several errors, like:
“2017-08-08 18:32:06.911 ERROR 28428 --- [nio-8472-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: ERROR: operator does not exist: timestamp without time zone > bytea”

The error does not tell exactly what the problem is, which is, in my opinion, the weakest characteristic of Spring Boot and Spring Data JPA logging. Nevertheless, I decided to add some converters as described in the JPA documentation.
Tip no 1: Always use appropriate documentation.

Please note that Converter is class that implements
javax.persistence.AttributeConverter
interface and You do not need any annotation on that class.
So my implementation looks like this:
import javax.persistence.AttributeConverter;
import java.sql.Timestamp;
import java.time.LocalDateTime;

public class LocalDateTimeConverter implements AttributeConverter { @Override public Timestamp convertToDatabaseColumn(LocalDateTime attribute) { return attribute != null ? Timestamp.valueOf(attribute) : null; }

@Override public LocalDateTime convertToEntityAttribute(Timestamp dbData) { return dbData != null ? dbData.toLocalDateTime() : null; } }

At this point, all I need to add is an annotation to my Entity fields that drives to the Converter class:
Convert(converter = LocalDateTimeConverter.class)

The final Entity looks like this:
@Entity
@Data
@Table(name = „tableA”, schema = „public”)
public class EntityA implements Serializable {
    @Id
    @SequenceGenerator(name=„tableA_seq”, sequenceName=„tableA_seq”, allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator=„tableA_seq”)
    private Integer id;
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime terminod;
    @Convert(converter = LocalDateTimeConverter.class)    
    private LocalDateTime termindo;

    … other entity stuff …
}

And BOOM :) everything work as expected.

Summary

There are many good mechanisms in Java 8 that You can use in Your Spring Data application, one of my favorite is Time API and with Converter mechanism You are no longer sentenced to javax.sql.* classes.

Autor

Opublikowany

What is JMS? Java Message Service could be considered as high level framework that communicates two or more clients each other by sending messages. JMS is fully supported by Java EE and has been specified in JSR -914 (see links section).
Base operations that we could done via JMS are:
- send messages
- receive messages
Typically one JMS client create message and send it to the server (JMS message broker) and other JMS client receive it and perform some operation. Of course this is high level overview and lower process is more complicated while added i.e. security and so on.

Where we use it? Well we could use JMS everywhere where we need increase scalability, integrate different environments, batch processing support, asynchronous communication without time pressure.
Common use is email sending process where one client create message that templates email should be send to appropriate receiver/s and send message to message broker where it is queued and receivers can download them when connected.

What are the key players on the JMS market? Below You could find my private favorite JMS vendors list:
- Amazon SQS
- ActiveMQ
- Oracle Weblogic
- HornetQ (perv. JBoss messaging) see link no 2

What is activemq? ActiveMQ is implementation of Message Oriented Middleware which is used to communicate ie via JMS clients. As we could read at official page (see link no 3) it is open source system that is fast, supports cross language clients and protocols and what’s the most important supporting fully JMS 1.1 specification.
Latest version is 5.x.x and this version will be used in demo.

Active mq server From the download section of official ActiveMQ page (see link no 3) You can download latest server binary package. After un-zip it took almost 100MB of disk space.
Unzipped binaries is all You need to start Your server.
At my windows machine starting script is located at: apache-activemq-5.x.x\bin. I use activemq.bat but there ale similar scripts for Linux too.
Bat script setup local env and finally run jar file called activemq.jar which is located at bin folder.

After run in command line starting script and successfully started server You should see something similar to:

Now You could type http://localhost:8161/admin/ to access Your ActiveMQ server administration console, note that default login and password is admin.

It should look like that:

Now You could add Your first queue in Queues menu.

ActiveMQ client example I created sample client for ActiveMQ server in Java 8 using threads and lambdas. Whole code You could find at my github: https://github.com/tjancz/jms-activemq-example.git

Below You could see sender code:

and the receiver code:

If You would like to see all working stuff just form my github repo.
There is also great documentation on ActiveMQ page.

Summary JMS is not scary as it looks and ActiveMQ is great MOM that could easily help You set up message queues and integrate different systems in MQ way.

Links
1. https://jcp.org/aboutJava/communityprocess/final/jsr914/index.html
2. http://hornetq.jboss.org/
3. http://activemq.apache.org/

Autor

Opublikowany

REST become web service standard some time ago. To be honest I do not believe that we need SOAP any more since all needed communication functionalities could be done in REST. Probably there are some cases when SOAP web services fits better than REST web services, but generally when I need web services I start with REST.

One of old but still efficient framework for creation of REST web services is Jersey [ Link ] .
So what is Jersey? From the documentation we could see:
‘Jersey is a Java based framework that help java developers creating RESTful Web services with variety of media types and abstract away the low-level details of the client – server communication.’ Well that sounds good for me. I treat it as framework for helping expose REST without many complicated configuration features. That’s really important if You would like to create something universal and easy to understand without additional useless technology stack.

One of nice features that convince me to use Jersey is easy integration with Jetty server.

Basic integration looks like that

public static void main(final String… args) throws Exception {
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath(„/”);

Server server = new Server(8080); //server.setHandler(new IndexHandler()); server.setHandler(context); ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, „/*”); jerseyServlet.setInitOrder(0); jerseyServlet.setInitParameter(„jersey.config.server.provider.classnames”, SampleResource.class.getCanonicalName()); server.start(); server.join(); }

For my project [ GitHub Link ] I used dependencies

def versions = [
        «jersey»: ’2.22.2»,
        «jetty» : ’9.3.7.v20160115»
]

repositories { mavenCentral()
}

dependencies { compile «javax.ws.rs:javax.ws.rs-api:2.0.1» compile «javax.servlet:javax.servlet-api:3.1.0»

compile „org.eclipse.jetty:jetty-server:${versions.jetty}” compile „org.eclipse.jetty:jetty-servlet:${versions.jetty}” compile „org.eclipse.jetty:jetty-servlets:${versions.jetty}” compile „org.glassfish.jersey.core:jersey-server:${versions.jersey}” compile „org.glassfish.jersey.core:jersey-client:${versions.jersey}” compile „org.glassfish.jersey.media:jersey-media-json-jackson:${versions.jersey}” compile „org.glassfish.jersey.containers:jersey-container-servlet:${versions.jersey}” testCompile group: «junit», name: «junit», version: «4.11» runtime «javax.servlet:javax.servlet-api:3.0.1» runtime «javax.ws.rs:javax.ws.rs-api:2.0.1» runtime „org.glassfish.jersey.core:jersey-client:${versions.jersey}” runtime „org.glassfish.jersey.core:jersey-server:${versions.jersey}” runtime „org.glassfish.jersey.containers:jersey-container-servlet:${versions.jersey}” runtime „org.glassfish.jersey.media:jersey-media-json-jackson:${versions.jersey}”

}

Please remember about runtime section, especial servlet api is needed.

What really nice is that Jersey is still developed and last release was in Feb 2017.

In my example You could navigate to http://127.0.0.1:8080/sample/hello and see

{"reasult":"hello"}
result.

Autor
Kategorie DSP2017, Java

Opublikowany

I’ve interested in Jetty web server couple years ago,
it has nice slogan „Don’t deploy your application in Jetty, deploy Jetty in your application!”.

I know that Spring Boot is fancy nowadays, but do we really need to create own stuff in fancy technologies?
Maybe we should choose good solution instead easy one?
Well I’m not telling that Spring Boot is not good, in fact I like it and use it sometimes, but it not fit to all cases.

OK if You are lazy and approve Spring stack You can use Spring Boot to all cases ;)
But I’m not and would like to have small ride with Jetty 9.

Let’s create hello world using that server.

What is Jetty, all should know – it is embedded web server which enable all including HTTP 2 capabilities to application.
Where could I get it – of course from maven central repository. I’m using Gradle and 9.4.x version in this hello ride.


compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.2.v20170220'


Basic setup is quite easy

public static void main(final String... args) throws Exception {
        Server server = new Server(8080);
        server.setHandler(new IndexHandler());
        server.start();
        server.join();
}


Just create jetty server object in main method and start it. Interesting thing is being done in setHandler method.
Well first we need to explain what really handlers are in Jetty?

I treat handlers as methods for operating on requests to produce response. Simple nothing more.

So if I would like to present hello world application above IndexHandler would look like that
public class IndexHandler extends AbstractHandler {
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        final PrintWriter out = response.getWriter();
        out.println("Hello from Jetty 9");
        baseRequest.setHandled(true);
    }
}

Form the official Jetty documentation [ Link ] passed parameters are:

  • baseRequest – the Jetty mutable request object, which is always unwrapped.
  • request – the immutable request object, which may have been wrapped by a filter or servlet.
  • response – the response, which may have been wrapped by a filter or servlet.

So for sure Spring Boot Hello World would be faster and containing less code, but Jetty 9 give You more freedom of choosing technology stack.

Autor
Kategorie DSP2017, Java

Opublikowany

Wstęp

Jakiś czas temu wpadłem na stronę konkursu „Daj się poznać”, fajna sprawa od jakiegoś czasu prowadzę bloga i stwierdziłem że może dzięki tej inicjatywie uda mi się bardziej systematycznie dodawać do niego treści.
Wielkie dzięki dla organizatora :+1: :D

Jednak nie o tym ma być dzisiejszy wpis.
W ramach konkursu jak i na użytek własny stworzyłem projekt open source pod zacnym tytułem own phone private backup [ Github: https://github.com/tjancz/ownPhonePrivateBackup ]. Idea jest prosta – robić backup istotnych rzeczy zapisanych na własnym telefonie.
Często łapię się na tym że kasuję wątki sms/mms, zdjęcia, pobrane pliki które ktoś mi wysłał bez zastanowienia, a później jednak okazuje się że były potrzebne. :)
Więc czemu by ich nie wrzucać na własny serwer i trzymać pewien czas zanim znikną bezpowrotnie?
Więc będąc zmotywowany do samorozwoju, mając cel przed oczyma zabieram się do pracy.

Analiza problemu

Pierwszym krokiem który każdy, hmm – „programista” powinien zrobić to przeanalizować problem.
Więc i ja to zrobię.
Cel Główny: Mieć backup istotnych danych zapisanych w moim ukochanym androidzie.
Założenia:
- Backup musi być absolutnie prywatny, żadnych publicznych chmur!
- Urządzeniem które backupuje jest mój android phone
- Serwer na który robię backup musi mieć stos technologiczny (fajne słowo) Javy – bo kocham Javę i już :D
- Backup musi się wykonywać w tle samoistnie ( inaczej już po tygodniu zapomnę by go robić )
- Dane z serwera ulatniają się po określonym w konfiguracji terminie

I to chyba wszystko jak na początek.

Fajnie wiem co chcę zrobić teraz wystarczy wymyślić jak i tu pojawia się magiczne słowo

Architektura

Jak dinozaur od razu pomyślałem: „Dla tego problemu idealnie sprawdzi się Klient-Serwer.”
Czemu, gdyż projekt w swym założeniu ma tworzyć backup jednego urządzenia w jednym miejscu.
Jednak czym naprawdę jest architektura klient-serwer?
Wikipedia [ https://en.wikipedia.org/wiki/Client%E2%80%93server_model ] definiuje architekturę klient serwer jako klienta który żąda zasobów i serwer który owe zasoby udostępnia.
Hmm i tu strzał w stopę w moim przypadku to serwer żąda zasobów od klienta, chyba że klient jest serwerem a serwer klientem (?) ;)
A może jak to zwykle w życiu bywa rzeczywistość jest bardziej skomplikowana?

Na pewno mam do czynienia z dwoma modułami, aplikacją androida – moduł 1 i aplikacją Java – moduł 2.

Analizując pobieżnie funkcjonalności mogę stwierdzić że
moduł 1:
- wysyła dane do modułu 2
- żąda odpowiedzi czy dane przechowywane są aktualne
moduł 2:
- pobiera dane
- odpowiada informacją o aktualności danych

Wygląda to trochę jakby jednak oba moduły były czasem klientami a czasem serwerami. Natomiast istotą jest tu kwestia inicjatora operacji. To moduł 1 inicjuje żądania a moduł 2 wykonuje na rzecz modułu 1 operacje i dostarcza wyniki.
Nawet jeśli przeanalizujemy przypadek wysyłania backupu to jednak moduł 1 inicjuje wysyłkę danych oraz oczekuję informacji zwrotnej o powodzeniu ich zapisu po stronie modułu 2.

Czyli jednak mam do czynienia z Client – Server :)

Ciąg dalszy nastąpi…

Pozdrawiam
TJ

Autor
Kategorie DSP2017