IvoNet

IvoNet

NOTE: This article might be being revised continuously because of new insights.

This blog describes how I created a couple of Docker images to demonstrate Keycloak.Important in this blog is that the whole process will be described. I attended a couple of keycloak sessions during Javaone this year and during these sessions the illusion was created that adding Keycloak as the security provider for your application is very easy and almost non-invasive for your code.What they did not tell you that configuring a server that could use keycloak was not as trivial.This blog will also expose a java web application with rest end-points to show how the auth works.

Journey

In this article I’ll try to find the answer to a couple of basic questions like:

Is there a marriage possible between AngularJS, Java and Maven?

Can it be done?

Should it be done?

Must it be done?

Here I’ll describe the whole process of making a Java Maven AngularJS seed project.This process will include the mistakes I make and the lessons learned.The whole goal is to create a setup that can be build by a Java developer, with no specific front-end skills.

Add Bower

The default place bower will install its dependencies is ./bower-components but as I want them to conform to the maven structure I will add a directive to the .bowerrc file we just created.Information hiding dictates that I won’t tell users that I manage stuff with bower.

1

2

3

{

"directory": "src/main/webapp/vendor"

}

This will tell bower to copy the downloaded packages to that place.

Add dependencies (by hand)

1

2

3

4

5

6

bower install angular#1.3.0-beta.14

bower install angular-route#1.3.0-beta.14

bower install angular-animate#1.3.0-beta.14

bower install angular-mocks#1.3.0-beta.14

bower install angular-loader#1.3.0-beta.14

bower install bootstrap

This should be enough for a first basic setup. You might want to change the versions.

Because I want to have an easy setup I want to eliminate all these manual steps so now I want to have a config file that helps me to do this automagically :-).The following command will help create a setup script for bower.

1

bower init

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

[?] name: java-angularjs-seed

[?] version: 0.0.0

[?] description: A java / maven / angularjs seed project

[?] main file: src/main/webapp/index.html

[?] what types of modules does this package expose?

[?] keywords: java,maven,angularjs,seed

[?] authors: IvoNet <webmaster@ivonet.nl>

[?] license: Apache 2.0

[?] homepage: http://ivonet.nl

[?] set currently installed components as dependencies? Yes

[?] add commonly ignored files to ignore list? Yes

[?] would you like to mark this package as private which prevents it from being accidentally pub[?] would you like to mark this package as private which prevents it from being accidentally published to the registry? Yes

...

[?] Looks good? (Y/n) Y

The resulting ./bower.json file should look something like:

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

30

31

32

33

{

"name": "java-angularjs-seed",

"version": "0.0.0",

"authors": [

"IvoNet <webmaster@ivonet.nl>"

],

"description": "A java / maven / angularjs seed project",

"keywords": [

"java",

"maven",

"angularjs",

"seed"

],

"license": "Apache 2.0",

"homepage": "http://ivonet.nl",

"private": true,

"ignore": [

"**/.*",

"node_modules",

"bower_components",

"src/main/webapp/vendor",

"test",

"tests"

],

"dependencies": {

"angular": "1.3.0-beta.14",

"angular-loader": "1.3.0-beta.14",

"angular-mocks": "1.3.0-beta.14",

"angular-route": "1.3.0-beta.14",

"bootstrap": "3.2.0"

},

"main": "src/main/webapp/index.html"

}

Now that I have this config file I should be able to add the dependencies with a command.But first to test it We need to remove the manually added dependencies :-)

1

rm -rf ./src/main/webapp/vendor

Now to test the try out the setup:

1

npm install

It should recreate it all again :-)

It will also add a folder node_modules to the project.These folders should be excluded from version control, but that will be done later

Add Karma

I want to use Karma as the testrunner for javascript.Create the ./src/test/javascript/karma.conf.js containing:

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

30

31

32

module.exports = function(config){

config.set({

basePath : '../../../',

files : [

'src/main/webapp/vendor/angular**/**.min.js',

'src/main/webapp/vendor/angular-mocks/angular-mocks.js',

'src/main/webapp/js/**/*.js',

'src/test/javascript/unit/**/*.js'

],

autoWatch : true,

frameworks: ['jasmine'],

browsers : ['Chrome'],

plugins : [

'karma-chrome-launcher',

'karma-firefox-launcher',

'karma-jasmine',

'karma-junit-reporter'

],

junitReporter : {

outputFile: 'target/test_out/unit.xml',

suite: 'src/test/javascript/unit'

}

});

};

Now we can run the unit tests by using the command npm test

Add Protractor

I want to use protractor as the end-2-end tester.Create the ./src/test/javascript/protractor-conf.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

'use strict';

exports.config = {

allScriptsTimeout: 11000,

specs: [

'e2e/*.js'

],

capabilities: {

'browserName': 'chrome'

},

baseUrl: 'http://localhost:8000/',

framework: 'jasmine',

jasmineNodeOpts: {

defaultTimeoutInterval: 30000

}

};

Now we can run the integration tests by using the command npm run protractor

This should result in a working unit test and it should keep on monitoring for test changes.If you change the test in controllersSpec.js to a wrong text you should see this almost immediately in the terminal window.

For this all to work we need a Java EE Container and Node.js just won’t do :-)I work with Glassfish for my test environment and deployed it.

And now we get:

Refactoring…

I stared a bit at the code and concluded that I’m not happy with the current state of affairs. Right now I have my javascript code in the src/main/webapp/js folder and it shouldn’t be there. According to maven rulez it should be in src/main/javascript just like java. I also want to have a minified javascript in the artifact and not the origional.

So added the folder and told maven it needed to recognize it as a resource folder.

Add the folling config snippet to the <build> tag in the pom.xml

1

2

3

4

5

6

<resources>

<resource>

<directory>src/main/javascript</directory>

<filtering>true</filtering>

</resource>

</resources>

now I moved all files in the js folder of the webapp to that folder and removed the js folder in webapp.Now I wanted the minifacation to work and the jslint. I used a maven plugin for that. After some trials and errors the following config seems to work the best.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<plugin>

<groupId>net.alchim31.maven</groupId>

<artifactId>yuicompressor-maven-plugin</artifactId>

<version>1.1</version>

<executions>

<execution>

<id>compress-js</id>

<goals>

<goal>jslint</goal>

<goal>compress</goal>

</goals>

</execution>

</executions>

<configuration>

<failOnWarning>true</failOnWarning>

<outputDirectory>target/app/js/</outputDirectory>

<nosuffix>true</nosuffix>

<excludes>

<exclude>vendor/**</exclude>

<exclude>**/*min.css</exclude>

<exclude>**/*min.js</exclude>

</excludes>

</configuration>

</plugin>

and a small change to the karma.conf.js. Change src/main/webapp/js/**/*.js to src/main/javascript/**/*.js. now the npm test should work again.

The mvn clean package command failed because my app.js didn’t get through the jslint step and that is just what I wanted. Fixed it and voila.

The code until now is checked in.

Intermezzo

Goals met:

AngularJS as the frond-end framework

Bower as the web package manager.

Javascript jslint

Javascript as resource

Javascript testing with Karma / Jasmine

Maven for minifying javascript

Maven as the build tool

Java EE 7 as the back-end language

bootstrap

CDI

Use Git as version control

Goals to be met:

Frond-end testing must also be able done during the maven build

Maven integration for javascript testing

So I guess that my main goal now is to get jasmine working with maven…

Add jasmine maven plugin

At first I removed all jasmine pom stuff to start from scratch. Then I added the most basic jasmine config to it.But that didn’t work at all. Which was actually logical but I had to do some reading to understand that :-). I had to tell (in the correct order) what the plugin already needs to know before it can test my personal javascript code. At this time this means that I have to tell it to load JQuery and Angular and the Angular mocks. That seemed to do a bit more but now it didn’t find any *Spec.js files and I had to tell the plugin where to find that and the sources.This seemed to work but I got terrible stacktraces. After some research I found out that it had nothing to do with my configuration but with htmlunit, which is used by default by the plugin. So I had to install phantomjs and configure it as the driver.

Add bower to maven

As I want to have the integration as complete as possible I want to have the initial bower install also part of maven. Again some research and for me the maven-exec-plugin seems a good solution:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<plugin>

<groupId>org.codehaus.mojo</groupId>

<artifactId>exec-maven-plugin</artifactId>

<version>1.3.2</version>

<executions>

<execution>

<phase>generate-sources</phase>

<goals>

<goal>exec</goal>

</goals>

</execution>

</executions>

<configuration>

<executable>bower</executable>

<arguments>

<argument>install</argument>

</arguments>

<workingDirectory>${basedir}</workingDirectory>

</configuration>

</plugin>

Now during the generate-source phase it will run bower and put all the javascript dependencies into src/main/webapp/vendor because that has been configured in .bowerrc and bower.json. Good stuff :-)

Clean

As the vendor folder in webapp is not part of our version control and cleanup is also part of the fun I added the maven clean plugin with a bit of configuration.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<plugin>

<artifactId>maven-clean-plugin</artifactId>

<version>2.5</version>

<configuration>

<filesets>

<fileset>

<directory>src/main/webapp/vendor</directory>

</fileset>

<fileset>

<directory>node_modules</directory>

</fileset>

</filesets>

</configuration>

</plugin>

Removed protractor

As I tend to use Fitnesse and Selenium (in comination) to do my end-to-end testing I decided to remove protractor from the project. I want to test against the real server with all stuff working before running e2e tests.

I had to refactor some stuff like the path to the javascript unit tests as I moved the other scripts to src/test/javascript and removing references to protractor.

Conclusion (for now :-))

I committed the whole seed project to github and except for the end to end tests it all seems to work. I don’t mind about that because I tend to use Fitnesse for these kinds of tests so I can test against the real server.

It is a learning process and to say that I’m completely happy with the configuration is to lie.

In this version of the seed project it was all about integration. Integrating the different worlds of front-end and back-end with all it’s tools.

The question remains if that should be the way to go? I don’t know yet. Decoupling these worlds might be better.

I tend to think that these worlds should only meet through services and the front-end and back-end should be build separately. But as I was writing this a colleague of mine told me that he really wanted a setup like this because he wanted the java developers to be able to build the whole project with a simple command like mvn clean install, because it cuts down on the learning curve.

Final conclusion: Who am I to judge?!

Extra’s

IDE Configuration

I assume IntelliJ because lets be real… There can be only one :-)I also assume that glassfish is already installed.

The first time you check out the project you should run mvn package or mvn exec:exec to get the vendor resources installed.

Now you can deploy to glassfish through the IDE but you will still not have the javascript resources copied to the right place. In order to get this to work you can tell IntelliJ to perform a step before every make (see the picture below)

Choose on yuicompressor:compress the right mouse option: Execute Before Make.

Now whenever you press cmd+F9 or ctrl+r the compressor plugin will do its thing and update the resources.

Cheerz,

Ivo.

Open Questions

Is Yeoman something to look at?

What about grunt? is it better?

Or Gulp?

Should I make the back-end and frond-end separate projects so they can be developed separately?

Related topics

In this article I’ll try to find the answer to a couple of basic questions like:

Is there a marriage possible between AngularJS, Java and Maven?

Can it be done?

Should it be done?

Must it be done?

Here I’ll describe the whole process of making a Java Maven AngularJS seed project.This process will include the mistakes I make and the lessons learned.The whole goal is to create a setup that can be build by a Java developer, with no specific front-end skills.