Blog

Spring Bootcamp – GETting Started

I was recently listening to the Arrested DevOps podcast, in the episode on Making DevOps Beginner Friendly guest Laura Santamaria talked about the importance of creating learning paths. A learning path, as the name suggests, is a series of articles or guides that walk someone through how to use a technology or practice. Learning paths differ from normal blog articles, like I have often done, which cover how to accomplish a very specific goal in isolation.

In the decade I have been working with the Spring Framework in general and the 5 years I have specifically worked with Spring Boot I have learned a lot, what to do, what not to do, and in some cases the why behind some of those answers. With many people working from home in response to the COVID-19 outbreak, seems an opportune time to go back to the basics.

In this series we will do a slow burn through Spring Boot, each article will be structured around the steps to do a complete a common task, but will take the time to explain what exactly the code is doing, what is happening in the background, as well as some of the why/best practices behind the tasks. The goal isn’t necessarily to break new ground in what Spring Boot can do, but to try to get a more well-rounded understanding of Spring Boot.

In this first article of the we will initializing a new Spring Boot project and create a couple of simple HTTP GET endpoints. So with that…

HOMAGE on Twitter:

Initializing a Spring Boot Project

Screen Shot 2020-03-27 at 9.05.06 AM

When starting a new Spring Boot project, one of the best places to go is start.spring.io. start.spring.io provides an interface for defining a project’s metadata as well as the ability to easily bring in many commonly used dependencies that should all be compatible to work with one another. Below demonstrates how to quickly initialize a project:

Note: If you are following along with this article you should bring in the spring-web and spring-boot-devtools dependencies.

Building Web APIs with Spring Boot

For many Java developers, a big part of their day is spent building and maintaining applications that service a Web API. Spring Boot makes building and maintaining really easy, which is a big reason why it has become so popular in the Java world.

After importing a new Spring Boot application into your preferred IDE, we can have an accessible endpoint with just these few lines of code:

Once added, starting the Spring Boot application should result in “Hello World!” being printed when you go to: http://localhost:8080/api/v1/hello.

Let’s look at the key elements from the above:

@RestController: This annotation marks to Spring that this class is a web controller, a class that serves as the interface to the Web for interacting with the internal application.

@RequestMapping("/api/v1/hello"): This annotation allows a developer to define the base path for the entire controller. All endpoints defined in this controller will be pre-fixed with /api/v1/hello.

@GetMapping: This annotation defines that the method helloWorld can be accessed as a HTTP GET.

With “Hello World” working, the second task when working with a new language or framework is to take in some user input to create a message. With a GET endpoint there are three ways of accepting input from a client; via the URL path, as query parameters, and as a request headers. Let’s look at how to reference values from each below.

Retrieve Values from the URL Path

To retrieve values from the URL path, in the @GetMapping you will need to define a variable in enclosing braces like above with {message}. In the arguments of the method an argument must be annotated with @PathVariable, if the name of the argument is the same as the variable in the definition of @GetMapping then Spring will automatically map it. @PathVariable has three fields:

name: Allows for manually mapping a url path variable a method argument.

required: Boolean for if the path value is required. Defaults to true.

value: alias for name.

Retrieve Values from the URL Query

Values can easily be retrieved from the query portion of an URL, the section of the URL after the “?” e.g.: ?firstName=Billy&lastName=Korando. Spring by default will attempt map query variables to the names of arguments in the method. So in the example URL query firstName and lastName will automatically map to the arguments firstName and lastName. @RequestHeader has four fields:

name: Allows for manually mapping a query value to a method argument.

required: Boolean for if the path value is required. Defaults to true. A HTTP 400 is thrown if a required value is not provided.

defaultValue: A default value for when the parameter is not provided. Will set required to false.

value: alias for name.

Retrieve Values from the Request Header

Retrieving values from a request header works very similarly to retrieving them from the URL query. Like with @RequestParam, @RequestHeader will automatically map the method argument name to the name of a header value. @RequestHeader has four fields:

name: Allows for manually mapping a header value to a method argument.

required: Boolean for if the path value is required. Defaults to true. A HTTP 400 is thrown if a required value is not provided.

defaultValue: A default value for when the parameter is not provided. Will set required to false.

value: alias for name.

String.format() or String Concatenate

Commonly when building a String in Java many Java developers build a String using concatenation like this:

"A message with a variable: " + var1 + " and another variable: " + var2 + " and more...";

Constructing a String this way can become difficult to read, and also be a formatting nightmare as the code is constantly changed because of slightly different formatting rules. When building a String it can be useful to consider using String.format() instead as demonstrated above. Readability can be a bit easier and there a number of pre-defined ways for printing things like dates available. For more information on how to use String.format() check out the official Javadoc: 8, 11, 14

Convention over Configuration

I am a longtime Spring user, my first experience with Spring was in 2010, using then Spring 2.5. While Spring was a significant improvement over frameworks I had used prior, initializing a new Spring project was still a difficult and and time consuming process process. Getting a static endpoint running as we have done in this article could take hours, even days, if starting truly from scratch.

We were able to accomplish in minutes with Spring Boot, what took hors before because Spring Boot uses a pattern called convention over configuration. In short Spring Boot has a number of default opinions, such as using an embedded Apache Tomcat server running on port ​8080. Many of of these opinions however can easily be change. If we needed to run our Spring Boot application on a different port, we can just set server.port. Using a different application server can be as easy as making a couple small changes to our build file.

Convention over configuration allows developers to focus on key business concerns, because in many cases using embedded Apache Tomcat and running on port 8080 is enough, especially in an increasingly containerized world. Understanding Spring Boot’s default opinions and how to change them will be a key element through out this series because there are definitely right and wrong ways of changing them.

Restart Revolution

As an application is being built there is often a need to rapidly iterate. This means rebuilding and restarting an application frequently. While the steps to rebuild and restart an application aren’t difficult, performing them can disrupt your “flow”. To address this the Spring team developed Spring Boot devtools. Spring Boot devtools provide two key features; automated start and, with browser extensions, live reload. Here is Spring Boot devtools in action:

To use Spring Boot devtools in your project, you will need to add it as a dependency in your build file like this:

Be sure to check out the user guides for more information on how to use Spring Boot Devtools including how to include exclude additional files, use it within a production system, using it on a remote system, and more.

Proper REST and API Best Practices

Like the code in a project itself, the usability and longterm maintainability of an API depends significantly on how well it is designed. Let’s review a few ways to improve the design of an API.

Version Your API

Probably the first, and also on of the easiest ways, to improve the design an API is to include in the URL the API version. In the examples about this was done with v1. Versioning an API allows it to more easily evolve over time as business and client need changes. When breaking changes are introduced, they can be included a new version of the API e.g. v2 and this much easier for clients to migrate to than forcing a hard and complicated switch if the same API endpoints are used.

Follow REST When Practical

Representational State Transfer, or REST, has become a popular architecture to follow when designing Web based APIs. REST was built upon the HTTP protocol, and while there are legitimate critiques that it might not always work well in every business case, there are a few good elements to follow such as; using the appropriate HTTP verb for the behavior of a endpoint e.g., for retrieving data a GET should be used, creating new resources should be a POSTDELETE for when an resource should be deleted.

Additionally proper usage of HTTP codes can be helpful as well; a HTTP 200 should be returned only when a request is successful. 400 should be returned, along with an appropriate message, when the client sends invalid or bad data. A 404 is also appropriate to return when a client requests a non-existent resource.

Fully following all of REST might not be possible or practical in all use cases, but following some of the key elements above can greatly improve the usability and maintainability of a API.

Conclusion

Spring Boot has been a revelation for the Spring developer community. Spring Boot has allowed developers to quickly build new applications while focusing on designing business valuable features for their organizations. As touched on in this article, there is also a lot of subtly to using Spring Boot.  Spring Boot is easy to get started with, but can take a lot to “master”, as even after five years I am still learning new things all the time. In this series we will continue to explore how to use Spring Boot to its full potential.

The code examples used in this article can be found in my GitHub.

How to Better Captain of the Enterprise with Apache Maven

Apache Maven is popular tool for project management and defining how a project should be built. It’s flexible, extendable, and, because of it’s aforementioned popularity, most Java developers have at least some experience with it, creating a virtuous cycle of its usage.

When an enterprise adopts Maven, a frequent goal is to use it’s features and mechanisms as a way to encourage, or even enforce, enterprise standards and to make project initialization and maintenance easier. Over my career I have worked at a number of organizations, both as a developer consuming POMs defined by architects and technical leads, and as an architect defining POMs that would be consumed across an enterprise.

From this experience I have learned some of the pain points and common mistakes enterprises make when trying to use Maven. Often these pain points and mistakes are borne from a lack of knowledge of Maven’s feature set and/or incorrect usage of features. In this article we will step through how to make Maven more flexible and easier to manage in an enterprise setting.

picard

Being a Better Parent (POM)

One of the most common ways an enterprise utilizes Maven is through the creation of an enterprise wide parent, or super, POM. Parent POMs can be a great tool for encouraging developers to follow enterprise standards and reducing bloat in child POMs be defining commonly used dependencies, plugins, reporting etc.. Parent POMs can also become a huge burden slowing down build times, bloating the size of artifacts, and causing other problems in projects that consume the parent.

Maven provides features though when defining a parent POMs that allow it to be more flexible; offering help when and where it’s needed, but also quietly stepping back when a project might have unique needs and requirements. Let’s take a look at some of these key features.

Dependency Management

When defining a parent POM a common mistake is to add a lot dependencies that are believed to be universally required, but simply are not. Downstream this can cause problems because while it was thought every project would need dependencies X, Y, and Z, in reality some projects don’t need dependency Y, and for other projects; dependency Z causes an error when present on classpath.

Maven does provide a feature that gives a nice compromise between offering assistance with which dependencies should be used, particularly which version of a dependency should be used, and also keeping child parent POMs “clean”, and that is with Dependency Management. Dependency management is easy to use, just define dependencies as normal, but enclose them dependencyManagement tags. Here is an example below of using dependency management:

In the child pom we need only provide the groupId and artifactId of a dependency and all the additional information: version, type, scope, is pulled down transitively.

Screen Shot 2020-01-07 at 12.34.49 PM

Dependency management strikes a nice balance for both downstream developers and the architects and technical leads who are responsible for parent POMs.

Downstream developers benefit by not having to worry as much about which version of a dependency to use, what it’s scope should be, or their projects becoming bloated because a parent POM is adding extra dependencies they do not need. Downstream developers also benefit as the POMs for their projects are “cleaner” as only the artifactId and groupId for a dependency needs to be defined.

Tech leads and architects benefit by still having a centralized location from which to manage dependencies for downstream projects, but not have to deal with the issues that come from imposing the usage of dependencies, had the dependencies been defined normally within a parent POM.

Plugin Management

The same problems with dependencies, can also happen with plugins, and for that Maven offers a similar solution with Plugin Management. When you have a frequently, but not universally, used plugin, defining the plugin with plugin management is a good option.

A common example of this would be the maven-failsafe-plugin. Every project should be using the maven-surefire-plugin to run unit tests, however not every project will need the failsafe plugin which is commonly used for executing integration tests (an example here would be a shared library which might not need to communicate with any remote systems).

By defining the maven failsafe plugin using plugin management, when a project needs to execute integration tests, they need only add groupId and artifactId for the failsafe plugin in their POM, and then all the configuration defined within the pluginManagement of the parent POM. Here is an example of using pluginManagement in a parent POM:

And then a child POM pulling down the configuration of the failsafe plugin:

Screen Shot 2020-01-07 at 12.35.21 PM

Properties

Maven POMs also have section for properties. Like with any feature in Maven, and most programming languages, the most local definition of a property overrides the value that’s pulled down from a parent. Importantly though this overriding also applies to how that property is used within a parent POM. In the below example I have defined the property my-org.version, in my parent POM and set it to 0.0.1-SNAPSHOT. Under my dependency management section I reference that property in the version field of ​my-org-starter-security. This means by default the version of ​my-org-starter-security will be set to 0.0.1-SNAPSHOT in any child POM. Here is the code snippet below:

However in a child POMs if the property of my-org.version is defined and set to 0.0.2-SNAPSHOT, then that project will use version 0.0.2-SNAPSHOT of my-org-starter-security even though the version field is not of that dependency is not defined.Screen Shot 2020-01-07 at 1.36.52 PM.png

This behavior would apply to anywhere where properties are used, not just to dependencies. Using properties can allow an easy way for downstream projects to change the version of dependencies they are using, as seen in the above example, or change the behavior of a plugin or reporting tool. As you are defining dependencies, plugins, etc. in parent POMs, strongly consider using properties instead of hardcoded values for fields downstream projects might want to change.

Looser Coupling with BOMs

For many enterprises parent POMs alone will be enough for handling dependency and project management concerns. However for larger enterprises, or an enterprise that works in a number of different domains, they might struggle using parent POMs alone. I experienced this at an organization where we created a whole tree of parent POMs that looked something like this chart:

Screen Shot 2020-01-08 at 2.14.09 PM

There were two major problems here:

  1. The tree was so top heavy that a change in the top POM kicked off a lot of downstream builds
  2. The development cycles between the organization wide parent POM and downstream POMs were not in-sync. So this created a lot of confusion in versioning. If the “Super Parent” had a major version change, should that require a major version change in downstream POMs? If a downstream POM had a lot of changes should it also increase it’s major version or should that only be tied to upstream changes?

This confusions led to  frustration for both the architecture team that I was a part of and the downstream developers as they were constantly finding issues and having to update parent POM versions.

In situations like this, it might be advantageous to use BOM’s, or Bill of Materials, so there is a looser relationship to an organization’s parent POM. A real world example of this is in the Spring framework, the Spring Cloud team publishes a BOM for managing the libraries that are associated with that project as they have a different release cadence from the Spring Boot and Spring Framework projects. You can view the BOM the Spring Cloud team produces here.

Going back the earlier example, instead of a complex tree of POMs and child POMs, a single “super parent” POM could be used and a pair of BOMs that cover the Web and Batch domains could be created. This approach likely would had been less work for the architect team that I was on, and a more pleasant experience for downstream developers as there would be fewer changes to consume.

Screen Shot 2020-01-08 at 3.25.01 PM

Shared Library POMs

In a recent article I stepped through how to create a custom Spring Boot starter. When creating a library that will be shared within your enterprise it’s important to take care when defining the library’s POM. A developer’s perception of a shared library can sour quickly if using it brings in extra dependencies, causes classpath conflicts, or leads to other problems. Let’s look at some strategies for when creating a shared library’s POM.

Scopes

Maven has several scopes that can be used to define when and under which circumstances a dependency should be included. The scopes are; compile, provided, runtime, and test.

  • Compile: is the default scope and means that a dependency must be available when a project is being built and packages in its artifact.
  • Provided: the dependency must be present when the project is being built, but will be provided by the system that will be executing the artifact.
  • Runtime: the dependency isn’t required to build the artifact but must be present when running the artifact.
  • Test: the dependency is only used as part of the test cycle, and not required at runtime.

Using these scopes correctly can help avoid unnecessary dependencies being brought and give developers consuming a library more control on what dependencies are being brought in.

Optionals

Some dependencies might be required only in certain circumstances. In my Spring Boot starter example,  my-org-starter-security, the starter could be used in a web context and a console context. To build the project the spring-boot-starter-web and spring-security-web dependencies needed to present, but only needed if the project consuming my-org-starter-security is a web project. By setting spring-boot-starter-web and spring-security-web as optional console developers don’t have to worry about a bunch of extra web libraries being brought in. Below is an example of setting some dependencies as optional in a POM file:

Examples at Scale

Small scale demonstrations on how to use the features highlighted in this article is one thing, but often new problems occur at scale or once business requirements are introduced. To see examples of these concepts applied at scale I would recommend checking out how the Spring team has structured their POMs which can be found on their project GitHub repos:

https://github.com/spring-projects/spring-boot

https://github.com/spring-cloud

Conclusion

Image of star trek next generation enterprise flying in space

Proper management of parent POMs and shared library POMs can make a world of difference in how smoothly an enterprise operates. Define them well and you have happy developers and architects who can explore more important questions. Define them poorly and you will find yourself stranded while you try desperately to fix problems.

This article focused on a few key features to make managing maven easier in most enterprise settings, it only scratches the surface of all that Maven can do however. If you want to learn more be sure to check out the official documentation, as well as this great article which steps through a full featured maven pom.

You can view the code for this article on my GitHub Repo.

Building a Custom Spring Boot Starter

Spring Boot has become incredibly popular since it was first released in 2013. Starting from scratch; a developer can have an application communicating with a database through RESTful endpoints that have security configured for them all within the span of an hour. This was a huge improvement over the often days it would take to accomplish similar tasks using just the core Spring Framework.

Spring Boot itself has some core functionality, but much of what Spring Boot application will be doing; communicating with a database, providing REST endpoints, and processing security on incoming requests, are supplied through starters. The Spring team, and third party vendors that integrate with Spring, have created many publicly available starters which can be seen on start.spring.io.

These starters are great, but organizations have domain specific concerns. Organizations typically only use certain database vendors, have specific requirements when implementing security, among many other needs. Here it can be beneficial to create custom Spring Boot Starters that incorporate these constraints and requirements. In this article we will walk through the process of creating a custom Spring Boot starter.

Not Just Another Shared Library

Organizations creating shared libraries to handle cross-cutting concern like data access or security isn’t new. What is new is the Spring team has provided several extension points within Spring Boot that can be used to improve the developer experience, these shared libraries are called “starters”. Improving developer experience can increase the active use of a library which can help in making sure standards are followed across an organization.

Starter Components

There are several extensions points the Spring team has provided for building starters they are:

  • Auto-Configuration
  • Conditionals
  • Metadata for Configuration

We will step through how to use each of these features when building a starter so that it; requires minimal configuration to be used, is flexible for a variety of scenarios, and provides developers with information they need to configure it.

We will use security, my-org-starter-security, as an example for building the custom starter. Security is a common concern for organizations, it is also something that require some amount of configuration, and also might need to behave differently depending on context. This will give us a good opportunity to flex out all the above features in a semi-realistic scenario.

You can find the code example used in this article on my GitHub.

Auto-Configuration

Spring Boot is often described as being “opinionated”, one of the ways this is done is through auto-configuration. Spring components can be automatically (automagically?) loaded into context without requiring developer intervention. This is great for making your starter easier to consume and also used correctly (i.e. ensure required classes/beans are loaded). To have a component be auto-loaded requires following a few steps:

1. Add spring-boot-autoconfigure as a dependency

For auto-configuration to work, and to have the appropriate classes available, the spring-boot-autoconfigure dependency must be on classpath. The dependency can be added directly, or indirectly by including another starter as a dependency. In my example I am using spring-boot-starter as a dependency.

2. Create a Configuration class

Create a normal configuration class like you would within a Spring Boot application and have it perform whatever required behavior you need. In this example we will have the @Configuration class load a UserDetailsService and PasswordEncoder into the application context.

Full class here.

3. Add spring.factories

Next we need to tell Spring Boot that the class ​SecurityConfig is a candidate for auto-configuration. To do this we need to create a file named spring.factories which needs to be located under the META-INF (typically this is located src/main/resources, like this). Within spring.factories we will add the following:

Now when a developer brings in the my-org-starter-security, the class SecurityConfig will be automatically loaded into the application context.

Conditionals

Auto-configuration is great, but there might be components you want to load only in a certain scenarios. In our hypothetical organization we will have both web based and console based applications. How security works in these scenarios would differ dramatically, however using conditionals we can have only the appropriate classes loaded into the application context depending on the scenario, this saves developers who are using our starter from a lot of headaches.

Spring Boot provides a lot of flexibility when it comes to defining conditionals, however in this example we will use a couple of pre-defined ones @ConditionalOnWebApplication and @ConditionalOnNotWebApplication. Let’s create a couple classes that will only be auto-configured conditionally.

1. Create configuration classes

Like above we will create a couple of standard @Configuration classes, however we will also need to annotate those classes with the appropriate annotations, @ConditionalOnNotWebApplication for NonWebSecurityConfig and @ConditionalOnWebApplication for WebSecurityConfig. The classes look like this:

Note: Conditional annotations can also be placed at the method level if needed.

2. Update spring.factories

The spring.factories file will need to be updated with these new classes to mark them as auto-configuration candidates.

3. Curate Your POM

I will cover this in-depth in a separate article, but a key element in building a good starter, particularly when using @Conditional, is setting up the POM for your starter correctly. Commonly Conditionals will be looking for the presence (or non-presence) of classes on classpath. In my starter POM I made use of optionals, which made consuming my starter easier for console applications:

Metadata for Configuration

Inevitably some amount of configuration is needed. Remembering the exact name for a property or the correct values to supply it with can be difficult. To address this the Spring team provides a mechanism for defining metadata about configuration properties which can provide developers with which properties are available, information about those properties, and hints on valid values.

There are several options for supplying configuration metadata.

1. Add the spring-boot-configuration-processor:

Before you can do anything with metadata you will need to add the spring-boot-configuration-processor to your pom file for the metadata to be generated:

2. Add META-INF/spring-configuration-metadata.json

Under the META-INF folder where we earlier added spring.factories you will need to create another file called spring-configuration-metadata.json which, as its name suggests, Spring will read to generate configuration meta data.

With the initial setup work done, there are several ways to provide configuration metadata. Below at two popular ways of doing this.

Defining metadata in spring-configuration-metadata

Metadata can be defined directly within the spring-configuration-metadata file. Here I am providing metadata on how to configure console security:

With this added, going into application.properties hints are provided saying that my-org.cli.security.required-role is a property, providing information on that property, and then with the hints field, valid values and their meaning can also be provided. This metadata makes configuring security for console applications much easier for developers.

Binding Properties to a Class

Within a @Configuration class I could just use a @Value to retrieve the value of my-org.cli.security.required-role. However I can also bind that property to a class as well, this is particularly helpful when dealing with several properties. To do this simply create a POJO and add a @ConfigurationProperties annotation to it. You will also need to give it a prefix that is the same as the groups value you defined in spring-configuration-metadata, so in this case my-org.cli.security.

Supply Properties to a Configuration Class

If we want to retrieve the values out of CommandLineSecurityConfigurer we will need to annotate a @Configuration class with @EnableConfigurationProperties({ CommandLineSecurityConfigurer.class }), like I did in NonWebSecurityConfig.

Fields and Javadoc as Metadata

Class fields and Javadoc can also be used to provide metadata for properties. I created a second properties class, WebSecurityConfigurer. In this class I have three properties, userEndpoints, adminEndpoints, unsecuredEndpoints, each with Javadoc attached. Because I use the same group name for the prefix in @ConfigurationProperties as I supplied above in spring-configuration-metadata, Spring will process the fields and Javadoc and generate property metadata from it. As can be seen in the screen shot below the code. Like above, the values supplied in applications.properties will be bound to the fields.

Screen Shot 2019-12-30 at 11.31.52 AM

Providing Sensible Configuration Defaults

Another way Spring Boot is described as being “opinionated” is through providing “sensible defaults”. A common way this is experienced is through the default port number Spring Boot uses of 8080. Providing default property values is super easy, as I have done above by initializing unsecuredEndpoints with "/public**". ​

Conclusion

Starters offer a lot of opportunities for organizations to improve the experience of their developers. This article only scrapes the surface of what is possible. Be sure to check out the provided links for more details on how to create starters as well as the official documentation:

Auto-configuration: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-developing-auto-configuration

Providing metadata: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-configuration-metadata.html

You can find the code example used in this article on my GitHub.

Travel Tips for Developer Advocates: Part Duex

I published a blog article back in October on my experiences with travel over my first year as a developer advocate. Since then I have thought of several more travel tips, and also learned a couple more, so here is a second article on the topic. If you are a Concur user, you might find my section on Concur trips particularly helpful.

Rapid Fire Travel Tips

  • If you are planning on working during a flight and are flying British Airways, it would be wise to avoid the exit row. British Airways does not allow ANY carry-on baggage to be stored under the seat in front of you. This can make retrieving/storing your work laptop more troublesome.
  • If you find yourself traveling to certain cities frequently, purchase a transit card if applicable. This will make using that city’s public transit easier.
  • Don’t put your passport in the wash, but if you do, dry it out immediately and place it under some heavy books and you should be fine. I have gone through border control in several countries since largely without issue*.
  • Get a passport carrier to hold your transit cards and also help prevent you from doing something dumb and putting your passport in the wash.
  • Check for promotions for hotels you stay at or airlines you fly with. Hotels and airlines frequently have promotions offering bonus points or additional credit towards status, but you have to register for them.
  • Because most hotels have a no fee cancellation policy as long as you cancel the reservation more than a week before the check-in date, it can be a good idea to book a hotel room for large conferences even if you aren’t sure yet you’ll be attending.
  • Before you fly, be sure to download podcasts, tv episodes, movies, or any other entertainment you might be interested in to your phone or mobile device. I’ve been on trans-Atlantic flights where the plane’s entertainment system was unusable for the entire flight!
  • Get a power pack and make sure it’s fully charged before long days of travel. Outlets might not always be available.
  • TripIt can be a great application for storing your travel itineraries, particularly if you have a busy travel schedule.
  • Most of the trouble came because after the second time I put my passport in the wash was the day I left for travel and my passport was a little more “rough” looking. I got a couple of questions during that day of travel, but have since gone through border crossings in several countries without issue.

Powering Through Concur

Concur is a widely used tool by organizations for administrating travel. There are a few other tools, but Concur is one of the biggest and a decent chance you will be interacting with it if you find yourself traveling a lot for work.

Initially I found Concur incredibly frustrating and difficult to use. Over the past year as I have become more familiar with Concur, I have found ways to make it, if not pleasant to use, definitely much more bearable. Below are some tips I have learned over the past year to make working with Concur a bit easier.

Searching for Hotels

Screen Shot 2019-12-23 at 10.37.51 AM

Concur has an option to search for hotels by “reference point” and it is actually pretty effective. Initially when looking for hotels I would painstakingly fill in the address for the conference venue. The reference point option is way faster and easier. It gives “Statue of Liberty” as an example of something to search for, but it can actually match on much less well known spots. For example in October I presented at the JFall conference which is held in the Pathé Ede cinema in Ede, Netherlands. Needless to say, this is hardly a well known location. Concur has no trouble locating it though:

Filter for Your Preferred Hotel Brand Easily

Once you narrowed down the geo-location of where you will be staying, you will need to select your hotel. In my previous article on travel I mentioned the importance of sticking to a single hotel chain. However chains like Marriott, Hilton, IHG, etc. operate under many different brands, and it can be difficult remembering which brands go with which chains, luckily Concur has the ability to sort by Superchain instead:

Screen Shot 2019-12-23 at 10.36.35 AM

Modifying Your Hotel Stay

You travel enough and you will run into situation where your travel plans will change. When your hotel is booked through Concur changing your check-in/check-out dates only takes a few clicks. Find your hotel reservation in Concur, and in the top right corner click “Change”. Modify your check-in/check-out dates as appropriate and you are all set. Using this feature I was able to modify two hotel reservations in all of five minutes when some of my travel plans got moved around.

Screen Shot 2019-12-23 at 10.55.37 AM

Filtering for Your Preferred Air Carrier

Screen Shot 2019-12-23 at 9.33.18 AM.png

Concur doesn’t have a way to filter for airlines like they have for hotel chains. This can make booking air travel a little frustrating until I learned a trick. Once Concur has finished retrieving flight information, you can filter by connecting airports which should be located on the bottom left of the page (it’s collapsed by default). By selecting for the major hubs your primary carrier flies through, the flights to choose from should be filtered much more closely to match your preferences.

Mind the Details When Booking Air Travel

Screen Shot 2019-12-23 at 11.19.55 AM

In the above image there are two flights going from Kansas City (MCI) to Barcelona (BCN) that look all most identical; they are both listed as American Airlines, the total travel time is about the same, and the price is also the same (I removed the actual prices for confidentiality reasons, but trust me they were the same). However if you look at the descriptions for the footnotes, the second option has one additional flight marked as being operated by British Airways (6153), expanding the details gives me this:Screen Shot 2019-12-23 at 11.25.18 AM

On my flight out to Barcelona the trans-Atlantic flight from Dallas (DFW) to London (LHR) is operated by British Airways.

Depending on your opinion of British Airways or American Airlines, this detail could have a fairly significant impact on at least the flying portion of your travel experience. With the first option the trans-Atlantic flight to Barcelona is operated by American Airlines, the second option it is operated by British Airways.

In my situation I would choose the first option because of I have grown accustomed to flying on American, but regardless it is important when selecting a flight to look at these details as it can make a lot of difference.

Conclusion

There’s a lot of trial and error involved when you make that transition from traveling only a few time a year to dozens. I hope these articles can help other people make that transition a bit more smoothly than I have.

I Wasted Days Because I Refused to Ask for Help

This week I have been working on a how-to article providing the step-by-step of building a Spring Boot starter. After reading through the documentation on the subject, I decided to start to put together my code example. A simple example of creating a starter to handle security configuration within an organization. Below is a live shot of me struggling with Spring Boot’s auto-configuration:

Person struggling to climb over fence instead of opening a gate

Like many developers, struggling with technology isn’t exactly an uncommon event as here is another occurrence from only last month:

After pounding my head on this auto-configuration issue, looking at the documentation, looking at other code examples, I eventually realized I needed help, so I “phoned a friend”:  Screen Shot 2019-12-19 at 8.42.07 AM

If you look at the timestamps, within a minute my colleague Ozzy Osbourne, yes that’s his real name, provided me with my answer. Like is so often the case, the problem was a trivial syntax issue, I incorrectly named a file spring.fractories instead of spring.factories.

Scope the Problem and Find an Expert

person saying they are an expertAsking for help is important, but there are better and worse ways of asking for it. In my case when I asked for help, I went to a slack channel devoted to Spring experts. I also knew the problem was with auto configuration. This gave my colleagues the information they needed to know where to look in my code. I scoped the problem, and turned to the people who knew the area well, leading to its rapid resolution.

Because IBM is a huge organization, I am fortunate in having many experts to turn to when I have a question. This is very different from my previous experience; most organizations I have worked at have numbered, in total, in the hundreds or low thousands, with the technical staff only a subset of that. If you work at a smaller organization where the number of “experts” you can turn to is limited I would recommend engaging in your local meetups to expand your network. I have gotten to many developers in my area, Kansas City, this way, which I have turned to for help on more than a few occasions.

Note: If you are a Java developer in the Kansas City area be sure to check out the Kansas City JUG.

Regardless when asking for helping either inside or outside of your organization you should be conscientious of those you are asking for help from. Everyone has their own priorities, so it’s important to scope a problem down as much as reasonably possible and also provide useful background information. This helps you as you don’t have to spend time re-treading tried solutions or chasing down red-herrings.

Pay it Forward

Humans operate on concepts of trust, reciprocity, and mutual respect. As you ask for help, it’s important to be mindful that you are asking someone else to take time out of their day to help you with something. When you scope a problem before asking for help, it shows a sign of respect to who you asked for help that you made a real attempt to resolve the issue yourself first (i.e. you value their time).

As you ask for help, you should also be attentive to others when they need help. I may not be in a position soon to repay my colleague directly by helping him with an issue, but I can still repay some of that goodwill by helping the next person who might ask a question in the Spring experts channel, or some other area I have expertise in.

Conclusion

Most of all what I hope you take from this article is it is ok to ask for help. Like many developers early in my career I was at times overly cautious about asking for help. I was afraid that by asking questions I might be revealing my ignorance and/or that I didn’t know what I was doing (see: imposter syndrome). It is something that every developer needs to works to get over. Even after a dozen years as a professional developer I still have been tripped up by a simple spelling mistake that cost me hours. Next time you find yourself spinning your wheels, scope the problem and find an expert.