Juzu Day 2: Real Web Apps as Well

Today, we will delve more deeply into Juzu Web Framework. We will see the differences between the Portlet and Servlet modes.

If you didn’t read part one, you can start by looking at: Three Days with Juzu: Write a Killer App.

So, let’s start with the fundamentals !

Portlets but not only

We will see now how easy it is to write a portlet with Juzu. Then, I will show the differences when working on a more standalone app using Servlet mode.

Portlet Application

Advantage

The biggest advantage I see when I develop a portlet is that it’s part of a platform that will allow a lot of things at a minimal cost. So, when you develop a portlet inside eXo Platform, you get for free:

  • Page management: just focus on the app, the page layout is taken care of on the portal side;
  • User management: call the services, you have your user, its profile, roles, etc., no need to manage it;
  • Social enablement: add social features for free in your app;
  • And a lot more services I don’t use in the Chat app but on others, like Document Management for example (see Documents Application for example).

Create a portlet

Well, with Juzu, it’s very simple, just follow the white rabbit.
You can build an application using:

mvn archetype:generate \
   -DarchetypeGroupId=org.juzu \
   -DarchetypeArtifactId=juzu-archetype \
   -DarchetypeVersion=0.6.0-beta5 \
   -DgroupId=org.example \
   -DartifactId=myapp \
   -DpackageName=org.example.myapp \
   -Dversion=1.0.0-SNAPSHOT

It will create a Hello World app you can start playing with. Everything is well described in the reference guide.

The generated app itself is very standard: it declares the portlet.xml file, uses portlet modes, can leverage portlet preferences, etc. So, what’s more? Its application declaration!

app:package-info.java

@Application(defaultController = ChatApplication.class)
@Portlet(name="ChatPortlet")
@Bindings(
        {
                @Binding(value = org.exoplatform.services.organization.OrganizationService.class),
                @Binding(value = org.exoplatform.social.core.space.spi.SpaceService.class)
        }
)

@Assets(
        location = AssetLocation.SERVER,
        scripts = {
                @Script(src = "js/jquery-1.7.1.min.js", id = "jquery"),
                @Script(src = "js/jquery-juzu-utils-0.1.0.js", depends = "jquery"),
                @Script(src = "js/chat.js", depends = "jquery"),
                @Script(src = "js/sh_main.min.js"),
                @Script(src = "js/sh_html.min.js"),
                @Script(src = "js/sh_java.min.js"),
                @Script(src = "js/sh_javascript.min.js"),
                @Script(src = "js/sh_css.min.js")
        },
        stylesheets = {
                @Stylesheet(src = "/org/benjp/assets/bootstrap/assets/bootstrap.css", location = AssetLocation.CLASSPATH),
                @Stylesheet(src = "/org/benjp/portlet/chat/assets/chat.css", location = AssetLocation.CLASSPATH),
                @Stylesheet(src = "/org/benjp/portlet/notification/assets/notif.css", location = AssetLocation.CLASSPATH),
                @Stylesheet(src = "css/sh_style.css")
        }
)

@Less(value = "chat.less", minify = true)


package org.benjp.portlet.chat;

You can see here how I can bind eXo Services in the app by just adding the @Binding annotation, it’s very simple.

In the META-INF of your project, just declare your provider (in my case a GateIn provider) and it will be automatic – provider factory file.

Next, you can attach assets to your app (portlet). Again, it can’t be easier than this. Use @Script for JavaScript and @Stylesheet for your CSS files.

You can notice two location scopes:

  • AssetLocation.SERVER: static files added in your webapp folder;
  • AssetLocation.CLASSPATH: files generated in your app assets (thus, compiled under classes at the end, accessed by their package).

In fact, the stylesheet chat.css targets the file generated by the @Less(value = “chat.less”, minify = true) at the end.

Finally, last but not least, @Less allows you to build Less files in your app and minify them.

All of the required classes will be generated at building time (in Maven in my case). So, no Less generation at runtime, it will be already checked and built (more efficient this way, don’t you think?).

Views vs. Resources

View methods

Now, if you want to render a view, use this annotation in your app controller – ChatApplication.java:

@View
  public void index(RenderContext renderContext)
  {
    remoteUser_ = renderContext.getSecurityContext().getRemoteUser();
    ...
    index.with().set("user", remoteUser_).render();
  }

You can see here how easy it is to access the RenderContext, add it as a param and it will be injected dynamically (gem number 1). @index refers to the inject groovy template (Juzu also supports Mustache templating and thanks to a plugin-based integration, you can create your own template plugin) – template injection example:

@Inject
  @Path("index.gtmpl")
  Template index;

I don’t use Portlet Preferences in this app but if you want to use them, just inject them in the Controller and you’re done:

@Inject
  PortletPreferences portletPreferences;

Again, it couldn’t be simpler than that (gem number 2).

Resource methods

Now, if you use jQuery like me, you will certainly do Ajax calls in your app. You can access a @Resource just like a @View:

@Ajax
@Resource
public Response.Content maintainSession()
{
  return Response.ok("OK").withMimeType("text/html; charset=UTF-8").withHeader("Cache-Control", "no-cache");
}

We will see later what @Ajax is used for.

Twitter Bootstrap Inside

I love Twitter Bootstrap because I can write a standard html application and it will take care of styling it. You don’t have to learn many new things, it’s just a very smart CSS (plus some JavaScript for advanced stuff). Thanks to Less integration, it’s very easy to setup bootstrap once you download the Bootstrap Less files

Using the same package-info.java class, you will generate Bootstrap with Juzu:

@Less(value = "bootstrap.less", minify = true)
package org.benjp.assets.bootstrap;

import juzu.plugin.less.Less;

So, now you can write views, call resources and use Bootstrap for the web design of your app. Here is what my application looks like:

Injection, injection, injection

I like this because it makes your code very neat and very easy to read. Plus, if I need to use a service, I don’t want to manage the configuration files, I just want it to work. Thus, if I write a service, I can use @Inject to get it – injection in ChatServer:

@Inject
  ChatService chatService;

or I can do the same with Constructor dependency injection

@Inject
  public ChatApplication(OrganizationService organizationService, SpaceService spaceService)
  {
    organizationService_ = organizationService;
    spaceService_ = spaceService;
  }

Templates

In the template, we can do a lot of things (it’s well explained in the ref guide). For the basic stuff, you can use the parameters you pass in the render() from the View method. Then, you access the param using groovy – index.gtmpl

<div id="chat-application"
  data-username="<%=user%>"
  data-session-id="<%=sessionId%>" 
  ...

If you take a look at the template, you can see how clean it is. No JavaScript, no extra stuff. Params are added as HTML5 data attributes so we can consume them later on client side. I use them when I need them:

var username = $chatApplication.attr("data-username");

Servlet Mode

In my Chat application, one of my prerequisites was zero-impact on eXo Platform. It means that if I add the Chat on a page, it cannot slow down eXo Platform, and it cannot jeopardize the Intranet performance because it would require too much CPU.

The first step toward achieving this was for the portlet to do almost nothing on the “main” server but to rely mostly on a dedicated “secondary” server. Of course, you can run in “one server” mode but I develop the entire app from the ground up to use a “two server” configuration. For more info about that, take a look at Chat Application github repo, it’s fully explained.

The second thing is to use asynchronous calls to avoid blocking a page load if the server is overloaded, for example.

If you go back to the screenshot of the app, you see I have in fact two portlets:

  • Notification app: shows your current status, allows you to change it and shows your unread message count;
  • Chat app: well, that’s the chat 🙂

So, because the notification is loaded on each page, I only take care of the main rendering in the index.gtmpl template.
Then, getting the current status is done asynchronously to the Chat server application using a jQuery ajax call.

Thus, I need a simple and efficient Chat server and that’s where Servlet mode is really great. If I was working on a web application running on Tomcat7 like I could do with Play, it would be the same with Juzu Servlet mode. You actually develop your app and your routes.

But I also write portlets and I don’t want to use one framework for my portlet and another one for the web application.

The great thing with Juzu is if you know how to write a portlet, you know how to write a web application (the opposite is also almost true since you just have to know what Portlet Preferences are, but nothing more). A web application is not declared in a portlet.xml but directly as a web app, thus, in the web.xml:

<web-app>
  <servlet>
    <servlet-name>JuzuServlet</servlet-name>
    <servlet-class>juzu.bridge.servlet.JuzuServlet</servlet-class>
    <init-param>
      <param-name>juzu.app_name</param-name>
      <param-value>org.benjp.portlet.chat</param-value>
    </init-param>
    <init-param>
      <param-name>juzu.inject</param-name>
      <param-value>weld</param-value>
      <!--
      <param-value>spring</param-value>
      -->
    </init-param>
  </servlet>
  ...
</web-app>

You do that and you can start developing the same way as you did with portlets. The only difference is routes.

Routes

So, same thing, you create a controller and declare it in a package-info.java descriptor. The only difference is using @Route annotation to access your server – like in the ChatServer:

public class ChatServer
{
  @Inject
  @Path("index.gtmpl")
  Template index;

  @Inject
  ChatService chatService;

  @View
  @Route("/")
  public void index() throws IOException
  {
    index.render();
  }

  @Resource
  @Route("/whoIsOnline")
  public void whoIsOnline(String user, String sessionId, String filter, String withUsers, String withSpaces)
  {
  ...
  }
}

You can see things are really similar and still so easy to read/implement.

Since the last release (and I don’t use it yet), you can even use regexp in the routes like on Servlet mapping (gem number three). So, at this step, we know how we can write an application, how to bind our services, how to write portlets, and how to use assets. But wait for tomorrow’s post, more is coming!

What’s Next?

So, that’s all for today but don’t miss tomorrow’s last post. We will see all the coolness of Juzu (maybe not all but some of it for sure!). By then, if you want to learn more about Juzu, go on its official website: http://juzuweb.org/.

« Again, thanks for watching and stay tuned – more things are coming, Benjamin. »

UPDATE: The last post of the serie, Juzu Day 3: The Coolness, has been published. It shows you all the coolness of Juzu like Responsive designs, jQuery and Less developments. Fluid App packaging is also there as a bonus.

Related Posts

1 Comment

    Leave a Reply

    Your email address will not be published.

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>