The Angular Mini-Book is a
guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and
deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.
Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with
Spring Boot and use security best practices like HTTPS and a content security policy.
This book shows you how to build an app with JHipster, and guides you through the
plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks
so you understand the underpinnings of your great application.
I like speaking at conferences. I don't enjoy the stress of creating a new talk and delivering it for the first time, but I do enjoy delivering talks, and I love the feeling after. It's even better when the conference provides an atmosphere that creates lasting memories.
I've been to many conferences in my career. A conference with a sense of community provides one of my favorite experiences. Not just for the people that attend, but for the people that speak. I've been to several conferences that provide this experience and I'm happy to say I just attended one of my favorites: Jfokus 2017.
I flew from Denver to Stockholm last Monday and performed my first talk on Testing Angular Applications just a few hours after I arrived on Tuesday. Usually, I take a day or two to recover from jet lag, but this time I figured I could clutch up and make it work. Going to sleep on the plane at 6pm Denver time certainly helped and I think the talk went well. For the live coding part of the presentation, I used the second half of my Angular and Angular CLI tutorial. I posted my slides for this talk to SlideShare and Speaker Deck. You can also view them below.
Tuesday night, there was a conference party. I met many new people and put some names to faces with a vibrant community of conference attendees and speakers.
The next time I do this presentation (at the Rich Web Experience), I'd like to see if it's possible to use all-Java to configure the Java EE 7 example. I used web.xml in this example and the Servlet 3.0 Security Annotations might offer enough to get rid of it.
All the demos I did during the security presentation can be seen in my java-webapp-security-examples project on GitHub. There's branches for where I started (javaee-start, springsecurity-start and apacheshiro-start) as well as "complete" branches for where I finished. The complete examples should also be in-sync with the master branch.
If you have any questions about either presentation, please let me know.
Security has always piqued my interest, ever since I first developed AppFuse and figured out how to make J2EE
security work back in 2004.
I hacked AppFuse to have Remember Me functionality,
then moved onto Acegi/Spring Security. Spring Security
had the features I needed, even if it did require almost 100 lines of XML to configure it. These days, it's much
better and its JavaConfig - combined with Spring Boot - is pretty slick.
That was the first part of my security life. The second phase began the night I met Trish, and learned she sold
security products. She knew of OWASP and their top 10 rules. It was Trish that inspired me to write my Java Web Application
Security presentation. I really enjoyed writing that presentation, comparing Apache Shiro, Spring Security
and Java EE's security frameworks. I followed up the first time I presented it with a
number of blog posts and
screencasts. Hmmmm, maybe I should update the presentation/screencasts to use Java configuration only
(#NoXML) and submit it to a couple conferences this year? I digress.
I had to do a security-related spike over the last couple weeks. I was trying to get SAML authentication working with
Okta and my client's Active Directory server. Luckily, someone setup the AD
integration so all I had to do was try a few different languages/frameworks. I searched and found ThoughtWorks' okta-samples, which includes examples using Node.js
and Sinatra (Ruby + JRuby). I also found a Spring
SAML example that includes one of my favorite things in JavaLand: Java-based configuration.
I'm happy to report I was able to get all of these applications working with my client's Okta setup. This article
will tell you how I did it. For each application, I created a new application on Okta using its "Template SAML
2.0 Application" and added myself in the application's "People" tab. Each section below contains the configuration
I used for Okta. The instructions below assume you're similar to me, a developer that has Java 8, Node and Ruby
installed, but none of the specific frameworks. As I write this, I have everything working on my Mac with Yosemite,
but I wrote the instructions below using one of my old laptops, fresh after a Yosemite upgrade.
In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on
AppFuse. AppFuse isn't used to start projects nearly as much as it once was. This makes sense since there's been a ton of innovation on the JVM and there's lots of
get-started-quickly frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.
You can see that AppFuse's community activity has decreased quite a bit over the years by looking at its mailing list
traffic.
Even though there's not a lot of users talking on the mailing list, it still seems to get quite a few downloads from
Maven Central.
I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it's a good place to
show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how
we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our
Generic DAO solution might be interesting as well.
Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some
opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to
maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between
different projects. I was able to leverage Maven's inheritance model to make a number of improvements:
This article is the third in a series on Apache Camel and how I used it to replace IBM Message Broker for a client.
I used Apache Camel for several months this summer to create a number of SOAP services. These services performed
various third-party data lookups for our customers. For previous articles, see
Part I: The Inspiration
and Part II: Creating and
Testing Routes.
In late June, I sent an email to my client's engineering team. Its subject: "External Configuration and
Microservices".
I recommended we integrate Spring Boot into the
Apache Camel project I was working on. I told them my main motivation was its
external configuration feature. I also pointed out its container-less WAR feature, where Tomcat (or Jetty)
is embedded in the WAR and you can start your app with "java -jar appname.war". I mentioned
microservices
and that Spring Boot would make it easy to split the project into a project-per-service structure if we wanted
to go that route. I then asked two simple questions:
Is it OK to integrate Spring Boot?
Should I split the project into microservices?
Both of these suggestions were well received, so I went to work.
To make sure these new services correctly replaced existing services, a 3-step approach was used:
Write an integration test pointing to the old service.
Write the implementation and a unit test to prove it works.
Write an integration test pointing to the new service.
I chose to start by replacing the simplest service first. It was a SOAP Service that talked to a database to
retrieve
a value based on an input parameter. To learn more about Camel and how it works, I started by looking at the
CXF Tomcat Example. I learned that
Camel is used to provide routing of requests. Using its CXF
component, it can easily produce SOAP web service
endpoints. An end point is simply an interface, and Camel takes care of producing the implementation.
Over the last several months, I've been developing a
REST API using Spring Boot.
My client hired an outside company
to develop a native iOS app, and my development team was responsible for developing its API. Our main task involved
integrating with Epic, a popular software system used in Health care. We also
developed a Crowd-backed authentication system,
based loosely on Philip Sorst's Angular
REST Security.
To document our API, we used Spring MVC integration for
Swagger (a.k.a. swagger-springmvc). I briefly looked into swagger4spring-web,
but gave up quickly when it didn't recognize Spring's @RestController. We started with swagger-springmvc 0.6.5 and
found it fairly easy to integrate. Unfortunately, it didn't allow us to annotate our model objects and tell clients
which fields were required. We were quite pleased when a new version (0.8.2) was released that supports Swagger 1.3
and its @ApiModelProperty.
What is Swagger?
The goal of Swagger is to define a standard, language-agnostic interface to REST APIs which allows both humans and
computers to discover and understand the capabilities of the service without access to source code, documentation,
or through network traffic inspection.
To demonstrate how Swagger works, I integrated it into Josh Long's
x-auth-security project. If you
have a Boot-powered project, you should be able to use the same steps.
A couple months ago, I was invited to speak at Virtual JUG - an online-only Java User Group organized by the ZeroTurnaround folks. They chose my Comparing JVM Web Frameworks presentation and we agreed I'd speak yesterday morning. They used a combination of Google Hangouts, live streaming on YouTube and IRC to facilitate the meeting. It all went pretty smoothly and produced a comfortable speaking environment. To practice for vJUG, I delivered the same talk on Tuesday night at the Denver Open Source Users Group.
I also updated all the pretty graphs (which may or may not have any significance) with the latest stats from Dice.com, LinkedIn, StackOverflow and respective mailing lists. Significant changes I found compared to one year ago:
A typical Maven and Spring web application has a fair amount of XML and
verbosity to it. Add in Jersey and Spring Security and you can have hundreds of lines of
XML before you even start to write your Java code. As part of a recent project,
I was tasked with upgrading a webapp like this to use Spring 4 and
Spring Boot. I also figured I'd try to minimize the XML.
This is my story on how I upgraded to Spring 4, Jersey 2, Java 8 and Spring Boot 0.5.0 M6.
When I started, the app was using Spring 3.2.5, Spring Security 3.1.4 and Jersey 1.18. The
pom.xml had four Jersey dependencies, three Spring dependencies and three Spring Security
dependencies, along with a number of exclusions for "jersey-spring".
Upgrading to Spring 4
Upgrading to Spring 4 was easy, I changed the version property to 4.0.0.RC2 and added the new
Spring bill of materials
to my pom.xml. I also add the Spring milestone repo since Spring 4 won't be released to Maven central
until tomorrow.
In preparation for my Grails vs. Play Smackdown at Devoxx France next week, I recently upgraded my Grails version of Happy Trails from Grails 2.0.3 to Grails 2.2.1. I ran into a few issues along the way and figured I'd document them here to help others out.
Fixing the source The first issue I ran into was Spock and Groovy 2 incompatibilities.
| Error WARNING: Dependencies cannot be resolved forplugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For moreinformation, see http://versioninfo.spockframework.org
I posted the problem to StackOverflow and got a response almost immediately. While this pull request helped me quite a bit, it was ultimately caused by my vision: I had two "geb-spock" dependencies listed in BuildConfig.groovy with different groupIds.
At this point, I also moved all my plugin dependencies from application.properties to BuildConfig.groovy.
The next problem I ran into was a unit test and functional tests failing. The unit testing issue was caused by my Direction model not being in the tests @Mock annotation. After I added it, validation kicked and I recognized my test was invalid. I added @Ignore and continued.
The functional test seemed to be seemed to be caused by Geb and it trying to use the Chrome Driver. One of my tests didn't work with the default HtmlUnitDriver, so I used the ChromeDriver for the one test.
| Running 11 spock tests... 6 of 11
| Failure: signup as a new user(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)
Even when running "grails -Dgeb.env=chrome test-app", this still happened. This was caused by the fact that I had GebConfig.groovy in test/functional/happytrails. Move it to test/functional solved the problem. I also discovered that I know longer needed Chrome to get this test to pass. Apparently, the HtmlUnitDriver has issues with Grails 2.2, but it seems to work for me.
After getting the Geb configuration fixed, I ran into a functional test failure:
| Running 11 spock tests... 5 of 11
| Failure: click signup link(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)
Even though I could see the "signup" link when I ran "grails run-app", I could see that it didn't show up when running tests in Chrome. This turned out to be caused by an extraneous <div class="nav-collapse"> I had in my main.gsp. Removing it solved the problem. It's strange that this never showed up with Grails 2.0. My only guess is that Geb someone didn't look at the visibility of the element.
The last testing-related issue I ran into was a InvalidElementStateException:
| Running 11 spock tests... 7 of 11
| Failure: add new route to region(happytrails.AuthenticatedUserSpec)
| org.openqa.selenium.InvalidElementStateException: Element must be user-editable in order to clear it. (WARNING: The server did not provide any stacktrace information)
I was able to fix this by changing AddRoutePage.groovy from:
And then referencing name, distance and location accordingly (form.name, etc.) in AuthenticatedUserSpec.groovy.
CloudBees
After I had everything working locally, I logged into Jenkins on CloudBees. Since I hadn't used it in a while, I had to wait a bit while my Jenkins server was re-commissioned. Once it was up, I tried to select Grails 2.2.1 to build with, but found it wasn't available. After a tweeting this, I learned about Grails Wrapper, found that the latest Grails Jenkins plugin supported it and got everything working. I later discovered that CloudBees does support Grails 2.2.1, I just needed to setup another Grails installation to automatically download and install 2.2.1.
Heroku
The last two issues I ran into were with Heroku. Since I was upgrading everything, I wanted Grails to build/run under Java 7 and use Servlet 3. I changed the appropriate properties in BuildConfig.groovy, configured Heroku and deployed. No dice.
Error Compilation error: startup failed:
Invalid commandline usage for javac.
javac: invalid source release: 1.7
Usage: javac
use -help for a list of possible options
Sidenote: I tried building with Java 8 on CloudBees, but discovered the searchable plugin doesn't support it.
Compile error during compilation with javac.
/scratch/jenkins/workspace/Happy Trails - Grails 2/work/plugins/searchable-0.6.4/src/java/grails/plugin/searchable/internal/compass/index/DefaultUnindexMethod.java:94: error: reference to delete is ambiguous
session.delete(query);
^
both method delete(CompassQuery) in CompassOperations and method delete(CompassQuery) in CompassIndexSession match
As far as Servlet 3, it was pretty obvious that the Jetty version Heroku uses for Grails doesn't support it. Therefore, I reverted back to Servlet 2.5.
java.lang.NoClassDefFoundError: javax/servlet/AsyncContext
at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)
I sent the Java 7 issue to Heroku Support a few days ago but haven't heard back yet.
Summary
While upgrading Grails from 2.0 to 2.2 wasn't as easy as expected, it is understandable. After all, Grails 2.2 ships with Groovy 2.0, which has a bunch of new features itself. All the issues I ran into were fairly easy to solve, except for Java 7 on Heroku. But hey, what do you expect from a free hosting service?
If you're at Devoxx France next week, I look forward to sharing our research on Grails 2.2.1 vs. Play 2.1.0.