Developing a web application with Spring Boot, AngularJS and Java 8

February 20, 2014 by Michael

And if you’re feeling
You’ve got everything you came for
If you got everything
And you don’t want no more

You’ve got to just
Keep on pushing
Keep on pushing
Push the sky away

“Push The Sky Away” by Nick Cave & The Bad Seeds.

This is gonna be a lengthy post about always learning new things and improving old ones.

This is gonna be the 1st post of a series about learning new things and creating a modern Java application from start. In the first part I’m gonna write about the idea, the tools and the project itself.

All posts

  1. Part 1: Boot your application with Spring Boot
  2. Part 2: Using Java 8 .now()
  3. Part 3: Messaging and Websockets with Spring 4
  4. Part 4: Spring Boot as a backend for AngularJS
  5. Bonus: Creating a JavaFX 8 frontend for a REST application

The idea and purpose of this thing

I had several reasons to create a project with well defined goals and requirements the way it should be.

The last weeks i had often discussions with current and possible future customers about the number or the price of my hours and i tried to tell them, that neither the price was too high or the number of estimated hours, especially the later, far from. I needed a reasonable sized and manageable project to prove this.

I also need to convince my colleges that near 100% test coverage and that database testing is possible and i also need to demonstrate that today a “one-guy-does-the-whole-stack” thing is nearly impossible if you don’t want to not sleep like me for about 2 weeks (or you’re just crazy about this stuff (also like me)).

And the most important reason for me is to learn something new, in this case learn about the new features in the upcoming release of Java 8.

Choosing the tools of the trade

Since 2010/11 i had real fun migration my daily picture project Daily Fratze from Ruby on Rails to Java, using the great Spring framework, so the first ingredient will be Spring but with it’s latest incarnation, Spring Boot: “Spring Boot favors convention over configuration and is designed to get you up and running as quickly as possible.”.

Certainly a new app will be written using Java 8. Just have a look at this post “Everything about Java 8” if you need reasons.

I need a database and i’m still a huge fan of relational databases and so i need some JPA 2.1. To make my life easier, i chose Spring Data JPA together with a little embedded H2 Database.

And finally AngularJS. I’m a little bit old school, i like my html pages server generated but i wanted to know what all the cool kids are doing and learn something fresh. Also, i thought it would be useful in the goal of designing a nice api.

Putting it all together with: NetBeans. I’m an Eclipse user since about 2002 and it’s hard to teach an old dog new tricks, but Eclipse has no Java 8 support. The alternative, IntelliJ didn’t really click with my. It incredible slow on an 2012 iMac with 16Gb Ram, doesn’t feel right to me and has some things i really hate (for example, what’s with those xml files that are created for every maven dependency?) so i thought why not given NetBeans another try.

I remember NetBeans being slow (and ugly), but 7.4 just proved me wrong. It’s fast and snappy and as i mentioned, it’s Maven support just outstanding, namely: It just works. Just 2 additional config files in a Maven project and that’s it. All the pain i had to go through to make Eclipse m2e work with generated source file, assisted JPA classes and aspects: It just worked in NetBeans. Awesome.

The project

Simple, recreating my Ruby / Sinatra based biking application: biking.michael-simons.eu. The original application is a very condensed Ruby script, which worked very well, but it’s not very maintainable.

So goto biking.michael-simons.eu and have a look. The thing is live and runs on the Java 8 release candidate. The source code is available at GitHub.

I’d be more than happy about comments, recommendations and ideas.

15 comments

  1. Martin Flower wrote:

    Hi Michael. Thank you for the hard work you have put into biking2. I am using it in order to deepen my knowledge of Spring Boot, Spring Security and AngularJS. I have taken the application and am porting it to Gradle and working with Spring Source Tool Suite.

    Right now it runs in the IDE – I navigate to localhost:8080, the browser prompts for username and password, and all urls I’ve tried return 404. My guess is that the application should be returning index.html instead – and not prompt for authentication. I expect I need to find out how to tell Spring Boot about index.html.

    Meanwhile, I can also tell you that the eclipse compiler can’t manage some of the functional programming in the source – but Gradle doesn’t have a problem using the Oracle Java compiler. I’ve commented out the bits it doesn’t like. (for the time being)

    Posted on September 16, 2014 at 10:39 AM | Permalink
  2. Michael wrote:

    Hello Martin,

    thanks for your feedback!

    Depending on the version of STS you’re using you might have chosen an older one whose version of Eclipse doesn’t support Java 8. Be sure to choose the one that is based on Eclipse 4.4, right now that should be 3.6.1.

    I’ve just checked the github version

    git clone https://github.com/michael-simons/biking2
    cd biking2/
    mvn clean && mvn package
    java -jar target/biking2-1.3.5-SNAPSHOT.jar
    

    and i can access the page right at http://localhost:8080/

    My current java version is 1.8.0_20.

    So: Spring should already now about the public pages, index.html among others.

    Have a great day and fun playing with that app.

    Posted on September 16, 2014 at 10:47 AM | Permalink
  3. Michael wrote:

    Just as additional info: Currently i’m using NetBeans 8.0.1

    Posted on September 16, 2014 at 10:49 AM | Permalink
  4. Martin Flower wrote:

    Hmm, I can load public/index.html, but we seem to be missing folder webjars. Would this folder be created automatically by Maven?

    Posted on September 16, 2014 at 11:57 AM | Permalink
  5. Michael wrote:

    Those are mapped by Spring Boot automatically.

    I think you should not use Eclipse “Run on Server” thing but just start the main-class “Application”.

    Posted on September 16, 2014 at 12:00 PM | Permalink
  6. Martin Flower wrote:

    Hi Michael – thanks for confirming that all works for you. The difference is that I’m using Gradle instead of Maven. Clearly, I need to spend more time on that conversion. : )

    I’m also not clear how to specify the active profile – does it default to prod?

    Posted on September 16, 2014 at 12:19 PM | Permalink
  7. Michael wrote:

    Sorry, my head mixed up gradle with grails… 😉

    Make sure you use the spring boot plugin for gradle http://docs.spring.io/spring-b.....lugin.html (the pendant for the maven one)

    Set spring.profiles.active to “prod”, either use a jvm system variable or set in application.properties, default is “dev”

    Posted on September 16, 2014 at 12:24 PM | Permalink
  8. Fernando T. Cabredo wrote:

    Hi Michael:

    I am using the latest STS for Mac and Java8. After importing your code, and executed mvn clean and mvn package, I got the error log messages below.

    I am excited to try your code in my machine. Thanks much.

    Failed tests:
    TracksControllerTest.testCreateTrack:270 Status expected: but was:
    TracksControllerTest.shouldHandleInvalidTcxFiles
    Expected: (an instance of java.lang.RuntimeException and exception with message a string containing “GPSBabel could not convert the input file!”)
    but: exception with message a string containing “GPSBabel could not convert the input file!” message was “java.io.IOException: Cannot run program “/opt/local/bin/gpsbabel”: error=2, No such file or directory”
    Stacktrace was: java.lang.RuntimeException: java.io.IOException: Cannot run program “/opt/local/bin/gpsbabel”: error=2, No such file or directory
    at ac.simons.biking2.api.TracksController.storeFile(TracksController.java:165)
    at ac.simons.biking2.api.TracksControllerTest.shouldHandleInvalidTcxFiles(TracksControllerTest.java:395)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
    Caused by: java.io.IOException: Cannot run program “/opt/local/bin/gpsbabel”: error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at ac.simons.biking2.api.TracksController.storeFile(TracksController.java:152)
    … 26 more
    Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:185)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    … 27 more

    Posted on December 7, 2014 at 9:28 AM | Permalink
  9. Michael wrote:

    Hello Fernando,

    thanks for your feedback.

    The app is using http://www.gpsbabel.org to convert Garmin Track files to GPX files. The easiest way to install it on your mac is probably through http://www.macports.org.

    The test calls the binary from /opt/local/bin/gpsbabel

    Hope that helps,
    Michael.

    Posted on December 7, 2014 at 10:17 AM | Permalink
  10. Marc wrote:

    Hi Michael

    Many thanks for your code and tutorial. It is very helpful to understand how to build a backend. I am trying to make all project run under eclipse luna (with Java 8 support). Currently I am getting 18 compile errors. Many of the are:
    The type ArrayList does not define add(Object, int) that is applicable here ChartsControllerTest.java /biking2/src/test/java/ac/simons/biking2/api line 112 Java Problem.

    Do you have any idea about this problem. Am I doing anything wrong?

    Many thanks in advance, Marc

    Posted on January 25, 2015 at 7:59 PM | Permalink
  11. Michael wrote:

    Hello Marc,

    thanks for your kind feedback.

    Unfortunately i haven’t work with eclipse for the best of the last year, but as Luna now officially has Java 8 that should be a problem. Apart from that, i’m quite sure that ArrayList does define that method.

    This is a maven project, you should use File / Import / Existing Maven project (or similar) to make sure Eclipse reads the pom.xml and sets all Java settings correct.

    The project does work and does compile. Maybe some tests fail when you don’t have a gpsbabel binary somewhere

    Have fun and success,
    Michael.

    Posted on January 25, 2015 at 8:04 PM | Permalink
  12. Marc wrote:

    Hi Michael

    Many thanks for your answer. I have imported the project as a maven import. All maven related dependencies could be resesolved. I have still one POM error: Plugin execution not covered by lifecycle configuration: org.jacoco:jacoco-maven-plugin.
    About the compile error for the arrayList: it says it needs an ArrayList add(Object, int). I was checking the ArrayList class. The class provides two add methods:
    1) public boolean add(E e)
    2) public void add(int index, E element)

    This means: it is looking for add(Object, int) but finds only add(int, Object). The same Problem is for the addAll(Object, Object).

    I will try to install NetBeans to see if it will give me the same problems.

    Thanks in advance.
    Marc

    Posted on January 26, 2015 at 1:56 PM | Permalink
  13. Marc wrote:

    Hi Michael

    I installed NetBeans 8.01 on Windows 8.1. I ve imported the project. It is compiling. gpsbabel is installed and running. I took care about the path of gpsbabel.exe in the TrackControllerTest.java.

    mvn install fails. You project assumes it is running under Linux. Did you try to make it run under Windows?

    spring:boot run is working. But http://localhost:8080 does’t give the desired result.

    It would be very helpful for eduction purposes and students to make this application run under windows. As a student and beginner with the current know-how it is almost impossible to fix it.

    Many thanks in advance.

    Regards Marc

    Posted on January 26, 2015 at 3:54 PM | Permalink
  14. Michael wrote:

    Hello Marc,

    actually, that project was developed on a Mac and on a Windows 7 PC. Believe me, it works.

    The comments about the list, i had a look: That *is* an Eclipse Problem. The statement is perfectly fine, Eclipse just still seems to have a problem determining the right type parameters.

    Regarding mvn install

    What is the exact error message?

    And to be honest, i’ve never used the boot maven task when running from an IDE, i just hit “run” button in netbeans or test the jar with java -jar biking2-whatever-snapshot.jar

    But i tried that for you

    mvn clean && mvn package && mvn spring-boot:run

    this works and the app starts, but indeed, the page is broken. Don’t know what’s going on here, seems to be a spring-boot maven plugin problem. Looking inside the directory i see that mvn spring-boot:run deletes all resources inside target/classes. Funny. Definitively broken.

    Just use
    mvn clean && mvn package
    and then
    java -jar target/biking2-1.5.2-SNAPSHOT.jar

    Posted on January 26, 2015 at 4:08 PM | Permalink
  15. Marc wrote:

    Hi Michael

    Many thanks for your quick response. Very kind.!!!

    The website is running in the meantime. The files under /webjars were missing. I have edited the index.html and I am using now the files from your site.

    The mvn package is still giving me failures. They come from Trackcontroller. I think it has still something to do with gpsbabel.exe.

    [Tests run: 9, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 2.451 sec <<< FAILURE! – in ac.simons.biking2.api.TracksControllerTest]

    It has still problems with the windows file name:
    "java.io.IOException: Cannot run program \"/iam/not/gpsBabel\": error=2, No such file or directory")

    I have tried to do a test with a new track by using the test.tcx file. It does not save.

    Many thanks in advance.

    Regards Marc

    Posted on January 26, 2015 at 5:15 PM | Permalink
11 Trackbacks/Pingbacks
  1. […] This is the first Post in my series Developing a web application with Spring Boot, AngularJS and Java 8. […]

  2. Using Java 8 .now() | info.michael-simons.eu on March 10, 2014 at 2:56 PM

    […] This is the second Post in my series Developing a web application with Spring Boot, AngularJS and Java 8. […]

  3. […] This is the third Post in my series Developing a web application with Spring Boot, AngularJS and Java 8. […]

  4. […] This is the fourth Post in my series Developing a web application with Spring Boot, AngularJS and Java 8. […]

  5. […] was looking for a nice solution to measure the code coverage in my Spring Boot biking […]

  6. […] Developing a web application with Spring Boot, AngularJS and Java 8: 4회에 걸쳐 스프링 부트(Spring Boot), 자바 8, 스프링 4.0, Angular.JS를 사용한 애플리케이션 개발 방법을 설명합니다. […]

  7. […] give something to code. Why not reusing the topic from my series of posts Developing a web application with Spring Boot, AngularJS and Java 8, which had gotten quite some attention of the last […]

  8. […] Boot”. Stéphane works on Spring Framework and Spring Boot from Belgium for Pivotal. Given my experiences the last 1,5 years with Spring Boot, i only can recommend not to miss this great opportunity to […]

  9. […] wish i could write a lengthy blog post how hard it was, to an API documentation to my biking Spring Boot demo project, but i […]

  10. […] That project is – in it’s current Spring based incarnation – with me since the first early access releases of Java 8 and the first betas and release candidates of Spring Boot (for example, see that post). […]

  11. Query all the things – info.michael-simons.eu on November 6, 2019 at 2:42 PM

    […] to work on that year. I had written extensive blog posts about that application (See the entry Developing a web application with Spring Boot, AngularJS and Java 8. This posts culminated not only in an application i used nearly everyday, but also in my very first […]

Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *