JShell at JavaLand – Slides

Yesterday I had my talk at JavaLand. It was all about Java 9’s great JShell, its API and a short view at its integration within NetBeans.

Mathias had been so nice to take this snapshot of my talk.

Although I prepared a lot of slides, I showed only a few one and demonstrated the JShell live. As I promised, I publish all my slides on this blog. Here the are: muellermiJShell.

Like my talk, the slides are in German. Maybe I’ll get a chance to repeat my talk in English somewhere…

I’m going to report a bit more about some JavaLand events soon.

Using WebSockets with Java EE, part 2.2

This post is part of my short series about WebSockets with Java EE.

  1. Technical aspects of the WebSocket protocol
  2. WebSockets in a Java EE 7 application
  3. JSF 2.3 and WebSockets

As I mentioned before, there are personal reasons which reduce my current time. Thus I divided part 2 into smaller sections. This is the second portion of the second part of my three part series.

So far, we created a very simple chat application using Java EE 7 technologies. In the first version of the simple chat, any message had been broad-casted by a tyrus session. Today I’ll show how to handle the broadcast by yourself.

An instance of our server endpoint is created every time the URL is opened within your browser. If you stay on that page, you may use the existing endpoint. If you like to verify that behavior, simply add a default constructor and report the construction.

  public SimpleChat() {
    System.out.println("ctor SimpleChat");
  }

Using Glassfish / Payara, the output is logged. You may call the logger instead. Using NetBeans you may observe this log directly in the output window of the IDE.

If an instance of the endpoint is created for every call to the URL, then we need to register all peer sessions who want to participate the chat. The simplest way to perform this task, is to use a static set of peer sessions.

  private static final Set<Session> peers = 
        Collections.synchronizedSet(new HashSet<Session>());

The server endpoint supports the annotations @OnOpen and @OnClose. The methods which are annotated with it, are called when the websocket is opened and closed and take a session as argument. Thus, these methods are the perfect candidates to register and unregister the peer sessions.

  @OnOpen
  public void onOpen(Session peer) {
    peers.add(peer);
  }

  @OnClose
  public void onClose(Session peer) {
    peers.remove(peer);
  }

Once we have registered all peers, we imply need to iterate them during @OnMessage and send the message to every peer. To perform that, we use getBasicRemote() to get a reference to the remote endpoint we want to send data synchronously. There is a second method getAsyncRemote() which can be used to send data asynchronously.

  @OnMessage
  public void onMessage(String message) {
    for (Session peer : peers) {
      try {
        peer.getBasicRemote().sendObject(message);
      } catch (IOException | EncodeException ex) {
        // log, handle, or ingnore exceptions here
      }
    }
  }

You may have recognized the different signature of the onMessage() method.  We don’t need the own session, thus we can use the overloaded method signature without it.

For your convenience, this is the whole endpoint class (without imports).

@ServerEndpoint("/simplechat")
public class SimpleChat {

  private static final Set<Session> peers = 
        Collections.synchronizedSet(new HashSet<Session>());

  @OnMessage
  public void onMessage(String message) {
    for (Session peer : peers) {
      try {
        peer.getBasicRemote().sendObject(message);
      } catch (IOException | EncodeException ex) {
        // log, handle, or ingnore exceptions here
      }
    }
  }

  @OnOpen
  public void onOpen(Session peer) {
    peers.add(peer);
  }

  @OnClose
  public void onClose(Session peer) {
    peers.remove(peer);
  }
}

To enhance the chat, we want to add the name of the sender to each message. And the user may choose a different chat room.

Time is over for today. I’ll write about this in the next (last) portion of part 2.

Stay tuned!

Using WebSockets with Java EE, part 2.1

Before my holidays I started this short series about WebSockets and announced more articles during February. The day I started working on this matter, my godson died. So I did (and will do) other things than writing.

I broke down my next article into two smaller pieces. One of them is the following writing. The other will be delayed. I assume your understanding.

This article describes the smallest possible chat I could write with JSF and websockets so far. JSF is only used to handle some elements within the browser. Within such a small application this might be handled with pure HTML/Javascript. But remember, this series is about JSF and websockets.

This article offers a step by step tutorial with NetBeans. If the IDE of your choice is a different one, it should be possible for you to transfer the steps. Or give NetBeans a try. You need to install the NetBeans Java EE (or the all) bundle.

From the NetBeans menu, choose File, New Project (or press Shift+Ctrl+N) to open the New Project window. Choose Maven and Web Application and click onto Next.

In the next screen provide a project name (SimpleChat) and within the last screen choose GlassFish (or Payara if installed) as application server. Then finish the wizard.

Once NetBeans created the project for you, right click the project and open the properties dialog. Add the JavaServer faces framework.

Click onto the Configuration tab and provide *.xhtml as URL pattern. Close the properties dialog.

Open the POM and add this dependenvy:

    <dependency>
      <groupId>org.glassfish.tyrus</groupId>
      <artifactId>tyrus-server</artifactId>
      <version>1.13</version>
    </dependency>

We will create another version without this dependency on Tyrus server in the next article. Using Tyrus, the endpoint will be the simplest.

For those, who don’t use NetBeans, here is the complete POM created and edited so far:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>de.muellerbruehl</groupId>
  <artifactId>SimpleChat</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SimpleChat</name>

  <properties>
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
    
  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.tyrus</groupId>
      <artifactId>tyrus-server</artifactId>
      <version>1.13</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
          <compilerArguments>
            <endorseddirs>${endorsed.dir}</endorseddirs>
          </compilerArguments>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.6</version>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <outputDirectory>${endorsed.dir}</outputDirectory>
              <silent>true</silent>
              <artifactItems>
                <artifactItem>
                  <groupId>javax</groupId>
                  <artifactId>javaee-endorsed-api</artifactId>
                  <version>7.0</version>
                  <type>jar</type>
                </artifactItem>
              </artifactItems>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

Next create a server endpoint as described in the first part of this series [1]. As name choose SimpleChat and as package name as well as endpoint URI use simplechat.

Modify the onMessage method

  @OnMessage
  public void onMessage(String message, Session session) {
    ((TyrusSession) session).broadcast(message);
  }

and fix the imports (Ctrl+Shift+I).

This method is called every time our endpoint receives a message. All it does, is to broadcast this message to all clients who have opened a websocket connection to the endpoint. Although it seems to be one broadcast, under the hood the server handles individual connections. Within the next part, we will do it by ourselves.

Next, modify the index.xhtlm page as shown below:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
  <h:head>
    <title>Chat</title>
    <h:outputScript name="simpleChat.js"/>
  </h:head>
  <h:body>

    <h1>Simple chat</h1>
    <h:form prependId="false">

      <div>
        Enter message: 
        <h:inputTextarea style="height: 1em;"  
            onkeypress="if (event.keyCode === 13) {
              acceptValue(this);
            }"
        />
      </div>
      <h:inputTextarea id="messages" 
         style="width: 100%; 
         min-height: 10em;"/>
    </h:form>
  </h:body>
</html>

This page defines two text areas. On is just a line height and is used for input. I’ve chosen a text area rather then a simple test field to stay within this field on hitting the enter key. As you can read, something happens on pressing that key. The other field is used for the common output. The glue code we need is provided within a JavaScript file simpleChat.js.

Within the projects web pages folder, create a new folder resources, and within that folder the file simpleChat.js. JSF will load this file according to the outputScript tag we have in our page. If you want to learn more about JSF resource loading, you may read my book Web Development with Java and JSF. Add this content to the script file:

var websocket;

window.onload = function () {
  invokeConnection();
}

function invokeConnection() {
  websocket = new WebSocket(obtainUri());
  websocket.onerror = function (evt) {
    onError(evt)
  };
  websocket.onmessage = function (evt) {
    onMessage(evt)
  };
  return true;
}

function obtainUri() {
  return "ws://" + document.location.host + "/SimpleChat/simplechat";
}

function onError(evt) {
  writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}


function onMessage(evt) {
  element = document.getElementById("messages");
  if (element.value.length === 0) {
    element.value = evt.data;
  } else {
    oldTexts = element.value.split("\n").slice(-19);
    element.value = oldTexts.join("\n") + evt.data;
    element.scrollTop = element.scrollHeight;
  }
  return;
}

function acceptValue(element) {
  websocket.send(element.value);
  element.value = "";
  return true;
}

Our simple chat is ready now. Compile and start the application. Enter some text and press enter: it appears in the output area. Open this app within a second browser and enter some text: it will appear in the output field within all browsers.

Let’s explain it:

When the page is loaded, invokeConnection is called. This method establishes a websocket communication channel to the server and registers two methods. onMessage is called for regular messages, whilst onError handles errors. Every time the client receives a message from the server (as send by the broadcast), it gets the text area we use for the output and appends the message. If a certain maximum is reached, it composes the message of the last few ones.

The method acceptValue is called every time the user hits the enter key within the input field. The message is send to the server and the input field is cleared to accept a fresh value.

Enjoy!

 

[1] blog.mueller-bruehl.de/jsf/using-websockets-with-java-ee-part-i

Black Sand

This photo shows the black sand of Tenerife. The colored ones might be fragments of colored glass or stones, each piece of approximate 1 mm in size.

What seems to be nice and colorful from the macro perspective, becomes a monochrome “black” (indeed dark grey) beach if observed from a greater distance.

JUGC: Java Web Development with TomEE and Vaadin – slides and more

In addition to my impressions of the JUGC evening about TomEE, Vaadin, Linkki and Arquillian, some of the speakers provided me slides and other documentation or links to it.


Andy Gumbrecht

This demo revolves around the MyBatis JPetStore 6 on Apache TomEE. It includes several examples on how to add EE technoligies to an existing legacy application. The slides are included in the project as odf and pdf. https://github.com/tomitribe/tomcat_to_tomee

The Arquillian Testing Framework demo project provides multiple examples. The slides are included in the project as odf and pdf. https://github.com/AndyGee/arquillian-demo


Jan Ortmann

JUG Cologne 2017-02-17


Teemu Suo-Anttila

Project link mentioned in my blog

Impressions from JUGC: Java Web Development with TomEE and Vaadin

On Friday, 17th we had another event at the Java User Group Cologne. An evening about Java web development with Apache TomEE and Vaadin. More than 40 Java enthusiasts participated that evening. The event was hosted by Faktor Zehn, the company which hosted the first NetBeans Evening Colonge, too.

The evening was scheduled from 6:30 pm till 10 pm. But due to a lot of informative stuff and many interactions with the interested attendees, it lasted till midnight. Frankly more than half of the attendees omitted the last talk, which started at 11 pm. Folks, even it had been really late, you missed an impressive talk!

Here some impressions of that evening (all photos by my, authorized by the speakers).

Andy Gumbrecht (Tomitribe) presents the application server Apache TomEE [1] and the micro profile [2].

Sami Ekblad (Vaadin) introduces the server side web framework Vaadin [3].

Teemu Suo-Anttila (Vaadin) hacks a short web application based on suggestions of the attendees. The result of the live coding is available online [4].

Jan Ortmann (Faktor Zehn) presents their framework Linkki to wire up applications with Vaadin. Unlike the other presented software this isn’t open source yet. But Jan promised it will become open source soon – just after polishing the code.

And the last talk introduced Java EE testing with Arquillian [5] (Andy again).

All in all this had been a very informative evening. If you missed this evening, you might vistit JavaLand in March. Most of the speakers will talk there. Me too. I’m going to talk about the new Java Shell.

Stay tuned!

 

[1] www.tomitribe.com

[2] microprofile.io

[3] vaadin.com

[4] github.com/tsuoanttila/cologne-jug

[5] arquillian.org

 

 

JSF 2.3 Public Review

The specification is now officially available for public review. Get it from the JCP site [1].

One of the big ticket features of this upcoming version is the easy usage of the WebSocket protocol. The expert group defined a <f:websocket> tag. As promised in my last article, I’m going to present a small application next month.

 

[1] jcp.org/en/jsr/detail?id=372

Using WebSockets with Java EE, part 1

The next version of JSF, 2.3 comes with the support of the WebSocket protocol. But can’t we use such with the current version of JSF (2.2)? Yes, we can. Using Java enterprise edition (Java EE) 7 you may create a so called endpoint. NetBeans support creating this out of the box, and it can be combined with JSF 2.2. Not as easy as the built in option of the upcoming version, but with high-performance for some special aspects. Continue reading “Using WebSockets with Java EE, part 1”