RSS

Category Archives: Jetty

Bringing together Docker, Grunt, Maven, EmberJS & MongoDB

Abstract : Will it work? … How can I be sure? … Am I forgetting something? … questions that pile up slowly and ruin our confidence once we cannot clearly answer them. For reasons like these we write tests – to be confident, to be certain, to sleep better. Yet, writing tests is one part of the problem. Getting them executed in an environment close to the production one is another . … and so, more questions pile up : How do we keep a snapshot of our production environment for testing purposes? What if our app needs to run in different environments? Can we keep multiple virtual environment snapshots? How many? Can we have test parallelization? Is the sandboxing guaranteed? and so on, and so on …

In this post, we are going to take a look at orchestrating Maven, Grunt & Docker to provide the basis for setting up integration tests.

Read more @ ingini.org

Advertisements
 
Leave a comment

Posted by on June 17, 2014 in Docker, EmberJS, Grunt, Guice, Java, Jetty, Jongo, MongoDB

 

Tags: , , , , , , , ,

Configuring Jetty with exploded web archives

Abstract : Having a great number of useful features, Jetty is one of the most popular servlet containers around. In this post we are going to prepare our test-bed with Jetty using exploded web archives (WAR) without any integrated development environment (IDE) plugins (such as IntelliJ Jetty integration plug-in or Eclipse Jetty Plugin).

Goal : Prepare a Jetty-enabled test-bed using exploded WAR content

Acknowledgement : My gratitude goes to the open source community and to the following people:

Arthur Kahn for presenting me with this challenge and for his help

Step 1 : Download Jetty and extract the Jetty archive in a convenient for you directory. I’m going to use Jetty version 8.1.4 but hopefully this post will be still valid for other versions.

Step 2 : Let’s say you’ve extracted Jetty in a directory called jetty_home. Make a copy of jetty.xml, called jetty-exploded-web.xml. You can find jetty.xml in jetty_home/etc and you should place jetty-exploded-web.xml there as well.

Step 3 : Make a directory under jetty_home called exploaded-context-deploy. We will put the web application context files of our web projects in this directory.

Step 4 : Add the following few lines to jetty-exploded-web.xml just before the closing tag:

    <!-- =========================================================== -->
    <!-- exloded web archives options                                -->
    <!-- =========================================================== -->
    <Call name="addLifeCycle">
        <Arg>
            <New class="org.eclipse.jetty.deploy.ContextDeployer">
                <Set name="contexts">
                    <Ref id="Contexts"/>
                </Set>
                <Set name="configurationDir">exploaded-context-deploy</Set>
                <Set name="scanInterval">1</Set>
            </New>
        </Arg>
    </Call>

Step 5 : Say we have two web apps: web-app-1 and web-app-2. We are going to put the web context files of these web applications in the jetty_home/exploaded-context-deploy directory. Both context files are quite similar except for the web app names, thus I’ll post the content of web-app-1.xml only:

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="contextPath">/web-app-1</Set>
    <Set name="resourceBase">/absolute/path/to/web-app-1</Set>
</Configure>

Step 6 : Comment the line etc/jetty.xml in the jetty_home/start.ini file and add the line etc/jetty-exploded-web.xml. Here is an example of start.ini file:

#===========================================================
# Start classpath OPTIONS.
# These control what classes are on the classpath
# for a full listing do
#   java -jar start.jar --list-options
#-----------------------------------------------------------
OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations,overlay
#-----------------------------------------------------------

#===========================================================
# Configuration files.
# For a full list of available configuration files do
#   java -jar start.jar --help
#-----------------------------------------------------------
etc/jetty-jmx.xml
#etc/jetty.xml
etc/jetty-exploded-web.xml
etc/jetty-annotations.xml
# etc/jetty-ssl.xml
# etc/jetty-requestlog.xml
etc/jetty-deploy.xml
#etc/jetty-overlay.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml

Step 7 : In order to run Jetty on port 8090 you have to execute the following from jetty_home:

java -Djetty.port=8090 -jar start.jar

Note that if you don’t provide the -Djetty.port=8090, Jetty will run on port 8080 by default.

Hot deploy : Note that Jetty is not going to automatically detect re-compiled Java classes, so one way to tell Jetty to reload a web app is to add a small change to the web app’s context file. For example if you have re-compiled web-app-1 adding a new line to web-app-1.xml web context file and saving it will be enough for telling Jetty to reload the project.

Remote debugging : If you want to attach a debugger (i.e. when using Eclipse, IntelliJ, etc.) to Jetty on port 8008 you have to run Jetty as follows:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8008 -jar start.jar

Extra classpaths : You can specify extra class paths for your web application by indicating this in the web context file, as follows:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 ...
 <Set name="extraClasspath">/extra/classes,/extra/extra.jar</Set>
 ...
</Configure>
 
Leave a comment

Posted by on July 22, 2012 in Jetty

 

Tags: ,

Skeleton of a JavaScript web application

Abstract: The present article will give a brief introduction to a way of building JavaScript based web applications using RequireJS (version 2.0.1), jQuery (version 1.7.2), Underscore (version 1.3.3.), Backbone.js (version 0.9.2), Backbone.Marionette (version 0.8.4), Handlebars (version 1.0.beta.6), TrafficCop (version 0.3.0), Maven(vesion 3.0.3), and Jetty (version 8.1.4.v20120524 used in embedded mode).

Acknowledgement
: My gratitude goes to the open source community, to the above mentioned projects, and to the following guys:
David Sulc – A simple Backbone.Marionette tutorial
Mavenizing Javascript Projects

Be aware: Since this example serves a static web content you may simply load the index.html file, however be aware that doing so may result in

XMLHttpRequest cannot load file:///… Origin null is not allowed by Access-Control-Allow-Origin.

If this happens you can either do as told below or look at: stackoverflow

The final goal of this tutorial will be to create a very simple modular structure for displaying project names. Let’s start. Here is what the structure of our final project will look like:

.
|-- pom.xml
`-- src
    |-- main
    |   `-- js
    |       `-- app
    |           `-- model
    |               `-- Project.js
    |               `-- Projects.js
    |           `-- view
    |               `-- ProjectView.js
    |               `-- ProjectsView.js
    |           `-- application.js
    |       `-- lib
    |           `-- backbone.js
    |           `-- backbone.marionette.js
    |           `-- handlebars-1.0.0.beta.6.js
    |           `-- require-jquery.js
    |           `-- TrafficCop.js
    |           `-- underscore.js
    |       `-- templates
    |           `-- project-template.html
    |           `-- projects-template.html
    |       `-- index.html
    |       `-- main.js
    `-- test
        `-- js

… and here is our pom.xml:

<?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>project-name</groupId>
    <artifactId>project-id</artifactId>
    <version>1.0</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>8.1.4.v20120524</version>
                <configuration>
                    <webAppConfig>
                        <contextPath>/${project.artifactId}</contextPath>
                        <baseResource implementation="org.eclipse.jetty.util.resource.ResourceCollection">
                            <resourcesAsCSV>src/main/js/,src/main/js/app</resourcesAsCSV>
                        </baseResource>
                    </webAppConfig>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The first thing we’re going to need is a base index.html file:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Project Knowledge Management</title>
    <script data-main="main" src="lib/require-jquery.js"></script>
</head>
<body>
<h1>Projects</h1>
<div id="content"></div>
</body>
</html>

As you can see (within the first highlighted row, line 5), this file has two references one to main which is actually a reference to main.js and one to require-jquery.js which you can download from here (this file contains jQuery inside, thus you don’t need a separate jQuery). Note that the second highlighted row (line 9) will contain our future content (this is going to be our hook point linked to application.js). So what’s inside main.js? Here it is:

require.config( {
    paths:{
        underscore:'lib/underscore',
        backbone:'lib/backbone',
        marionette:'lib/backbone.marionette',
        handlebars:'lib/handlebars-1.0.0.beta.6',
        TrafficCop:'lib/TrafficCop',
        app:'app/application',
        projects:'app/model/Projects',
        project:'app/model/Project'
    }
} );

require([ 'jquery', 'TrafficCop', 'underscore', 'backbone', 'marionette', 'handlebars', 'app','projects', 'project'],
        function ( $, TrafficCop, _, Backbone, Marionette, Handlebars, App, Projects, Project) {
                  Backbone.Marionette.TemplateCache.loadTemplate = function(templateId, callback){
                    var tmpId = templateId.replace("#", "");
                    var url = "templates/" + tmpId + ".html";
                    var promise = $.trafficCop(url);
                    promise.done(function(template){
                      callback.call(this, Handlebars.compile($(template).html()));
                    });
                  }

            var projects = new Projects([
                             new Project({ name: 'First Project' }),
                             new Project({ name: 'Second Project }),
                             new Project({ name: 'Third Project' })
                             ]);
                    App.start({projects: projects});
        }
);

Yes, you’ve guessed it, the fun start here. The necessary ingredients you can download (and place in the lib folder) from here: underscore, backbone, backbone.marionette, handlebars, TrafficCop. Well that was all of the external libs, now comes the time to build our internal business project structure. First we are going to need a model of a project, thus we are going to create a simple Backbone.js model within a file called Project.js:

define(['backbone'], function(Backbone){
         var Project = Backbone.Model.extend({});
         return Project;
});

As you can see, there is not much interesting inside since our example is really only a skeleton. After we have our main domain model, we are going to need a collection of them, thus comes the Projects.js:

define(['backbone', 'model/Project'], function(Backbone, Project){
         var Projects = Backbone.Collection.extend({
           model: Project

         });
         return Projects;
});

So far so good. Next we are going to need an entry point, that being the application.js:

define(['view/ProjectsView'], function(ProjectsView){
var App = new Backbone.Marionette.Application();
         App.addRegions({
           mainRegion: "#content"
         });

         App.addInitializer(function(options){
           var projectsView = new ProjectsView({
             collection: options.projects
           });
           App.mainRegion.show(projectsView);
         });
         return App;
});

Note line 4, this is the reference to our hook point in the index.html file. As you can see from line 8, our App has a reference to a view called ProjectsView for which we have a JavaScript file called ProjectsView.js and having the following content:

define(['marionette', '../view/ProjectView'], function(Marionette, ProjectView){
         var ProjectsView = Backbone.Marionette.CompositeView.extend({
         tagName: 'table',
         id: 'projects',
         className: 'table-striped table-bordered',
         template: '#projects-template',
         itemView: ProjectView,

         appendHtml: function(collectionView, itemView){
         collectionView.$("tbody").append(itemView.el);
         }
         });
         return ProjectsView;
});

The ProjectsView is a composite view based on ProjectView described in ProjectView.js:

define(['marionette'], function(Marionette){
         var ProjectView = Backbone.Marionette.ItemView.extend({
          template: '#project-template',
          tagName: 'tr',
          className: 'project'
         });
         return ProjectView;
}); 

The highlighted rows in both ProjectsView.js and ProjectView.js indicate the names of the required templates which can be found in templates directory. The first, projects-template.html, looks like this:

<script id="projects-template" type="text/x-handlebars-template">
    <thead>
    <tr class='header'>
        <th>Project Name</th>
    </tr>
    </thead>
    <tbody>
    </tbody>
</script>

The second, project-template.html, looks like this:

<script id="project-template" type="text/x-handlebars-template">
    {{name}}
</script>

Running our example is as simple as doing mvn jetty:run. Oh, and of course you can go to localhost:8080 and browse the result.