What’s a Bill of Material BOM file?

Wikipedia says:

A bill of materials or product structure (sometimes bill of material, BOM or associated list) is a list of the raw materials, sub-assemblies, intermediate assemblies, sub-components, parts, and the quantities of each needed to manufacture an end product. A BOM may be used for communication between manufacturing partners or confined to a single manufacturing plant. A bill of materials is often tied to a production order

https://en.wikipedia.org/wiki/Bill_of_materials

In the world of Java and Maven that boils down to some important Maven concepts.

  • The packing type
  • The dependency management tag
  • The fact that build files can import other build files

The packing type

Maven build descriptors (or “project object models”, in short pom (take note of the p)) can have different packaging: pom, jar, maven-plugin, ejb, war, ear, and rar. Standard is jar.

The type pom doesn’t produce an artefact but is the artefact itself. It is used for parent poms in multi module setups for example.

Poms can also be imported into other poms, into their dependency management, to be precise:

Dependency management

The manual has everything to get you covered. Here’s the important details from Dependency Management:

For BOMs we are not talking about the <dependencies />-tag but <dependencyManagement/>. Inside the dependency management tag, dependencies, their version numbers and exclusions are specified. Much as you would do inside the top-level dependencies tag.

The dependency management tag however does not declare dependencies. This still needs to be done, but one can omit the versions now. For examples, look at the link above.

Now two important facts: The dependency management propagates to child modules and one can import POMs with packaging pom into dependency management.

Import others peoples dependencies

Have a look at Project Reactors BOM: reactor-bom.

Project Reactor doesn’t consist of one single artefact and or multiple artefacts having the same version numbers. Instead of forcing users to keep track of all those version numbers and import single dependencies, one does import the whole bom:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-bom</artifactId>
      <version>Californium-SR32</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

After that, you pick what you want in dependencies, without version numbers:

<dependencies>
  <dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
  </dependency>
</dependencies>

So now you have the bill of materials, from which you can pick.

Doing more cool things with it

Now Maven allows to define properties inside <properties/>. Those properties can be reused in dependency declarations and inside dependency management.

Instead of hardcoding Californium-SR32 inside the example above, you would do:

<properties>
  <reactor-bom.version>Californium-SR9</reactor-bom.version>
</properties>
 
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-bom</artifactId>
      <version>${reactor-bom.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

Now you can switch to another version of the dependency or in this case of the whole dependency management by just setting one property.

This is

How Spring Boot works

Spring Boot uses exactly that mechanism for all supported dependencies. See Neo4j-OGM you would define the following in your Maven POM file:

<properties>
  <neo4j-ogm.version>3.1.13</neo4j-ogm.version>
</properties>

This updates the version of all dependencies of Neo4j-OGM, and not only the one you might remembered.

It works exactly the same with projects using a BOM, for example Jackson:

<properties>
  <jackson.version>2.9.9.20190807</jackson.version> 
</properties>

In a Gradle project, things need a second file, gradle.properties. I have written about it before. For the above example, that file would look like this:

jackson.version = 2.9.9.20190807

Here’s the full example.

TL;DR

Many projects use BOMs these days. Import those whenever possible and then pick the dependencies your need from the projects without specifying individual versions.
In the case of Spring Boot, never overwrite managed dependencies in your own dependencies, but use a property. Both for plain dependencies as well as for BOMs.

| Comments (1) »

22-Aug-19


Spring Security 5.1: Upgrade / Rehash stored passwords

In this post from early 2018, I described the new password infrastructure of Spring Security 5.0. As the post got some feedback the last couple of days, I jumped back a bit into Spring Security code and noticed this method here: PasswordEncoder#upgradeEncoding. Hm, what does it do?

It turns out, it works together with the additional, new interface UserDetailsPasswordService respectively ReactiveUserDetailsPasswordService.

TL;DR version: The delegating password encoder checks by default, whether the password hash’s id is present and matches the id to encode (see linked post above). If so, all is fine. Otherwise, the password needs an upgrade.

In my example application, I used an in-memory user details service with a user “michael” and password “SIMONS”, stored as a ROT-13 “hash” (I’m still waiting to see BSPasswordEncoder in production somewhere). The hash has of course no prefix. While I of course never used a password encoder like this, I migrated several applications hashed passwords from sha1 to bcrypt and pbkdf2 with a similar mechanism.

With the lastest commit I could remove all my custom ceremony for an upgrade. (see Upgrade to Spring Boot 2.1.7 and rely on PasswordEncoder#upgradeEncoding.). As the InMemoryUserDetailsManager is also a UserDetailsPasswordService, Spring Boot wires everything smooth and nicely for me.

The InMemoryUserDetailsManager of course just changes the in-memory hash.

A fictive, JDBCTemplate-based UserDetailsPasswordService could look like this:

public class JdbcUserDetailsPasswordService implements UserDetailsPasswordService {
    private final UserDetailsService userDetailsService;
 
    private final JdbcTemplate jdbcTemplate;
 
    public JdbcUserDetailsPasswordService(UserDetailsService userDetailsService, JdbcTemplate jdbcTemplate) {
        this.userDetailsService = userDetailsService;
        this.jdbcTemplate = jdbcTemplate;
    }
 
    @Override
    public UserDetails updatePassword(UserDetails user, String newPassword) {
        jdbcTemplate.update("UPDATE users SET hashed_password = ? WHERE username = ?", newPassword, user.getUsername());
        return userDetailsService.loadUserByUsername(user.getUsername()); // reload the whole user details
    }
}

The most important thing here is the fact, that UserDetailsPasswordService#updatePassword actually get’s the newly hashed password! A clear separation of concern, the update mechanism doesn’t need to know anything about the new hash that is used, it just has to store the string version of it! Apart from that, my version here reloads the complete UserDetails from a UserDetailsService not shown here. The implementation would be JDBCTemplate-based, too, in this case.

I really like this addition:

| Comments (1) »

15-Aug-19


Oh, all that entitlement…

There was a tiny tweet yesterday, resurrecting a talk from Christin:

Here’s the direct link to the talk: “Hibernate should be to programmers what cake mixes are to bakers: beneath their dignity.”.

I’d like to emphasize that I would have maybe thought so some 15 years back, too.
Today I cannot understand this whole setup of patronizing so many things at once.

The tweet linked above cause many threads. You have to digg through them a bit, but the most interesting ones are the discussions around Gavins, Gunnars and Johannes’ answers.

I am not a Hibernate fanboy, I’m a regular Hibernate user though. I’m however very much a database fanboy, as long as there is a great, declarative query language (PSA: I work for Neo4j, use Cypher a lot to provide and work in a team that creates an Object Graph Mapper (OGM)).

I firmly believe in the fact that there are no silver bullets and having only one idea is a super dangerous situation:

Having said that, I actually don’t to take the discussion about SQL and Cypher vs ORM and OGM any further.

I’d like to point out that I find several things with the heated discussion yesterday more than odd:

We all started somewhen and somewhere. With no knowledge, some knowledge, good or bad intuition. But we started and learned stuff. As a matter of fact, I just wrote about it the other week. One very important step on the way of becoming a senior something is actually realizing that other people may have less or other knowledge and working with that, helping them, instead of condescending them.

Second: I like cake mixes. I also like fresh, hand made apple pie.

Most of the years, I take the time with the kids to bake a cake for my wife’s birthday. You know what: We go and buy a cake mix and the missing, liquidish ingredients, mix the stuff up and spent the time we saved on decorating the cake, our table and whatnot.

On the other hand, going out for a coffee, either in a café or visiting friends being great with baking: Most awesome! And sometimes, when I’m really in for the mood, I do bakery with all the things necessary myself.

Having the possibility to chose between these options is entitlement, not everyone has: There are enough people that don’t have these simple choices, for whatever reasons.

Leaving the analogies behind: In now nearly 20 years of working in IT, I always had choices and good options. I could try out various frameworks, far beyond the “getting started guide.” Not on my spare time, but on the job. This such a big advantage. Yes, I know there are voices that people have to invest their own time to learn, but you know what? Being able to do this… well is entitlement, too. It’s ok to only work a regular 8 hours shift.

Today I understand better that people just want to use things. Many people work in projects under such high pressure, there’s just no room to get everything used right and even less room to recreate all the stuff by themself.

I think we should be happy, that we can choose from so many actually good ready to use ingredients, being it Hibernate, Spring, Grails, Spring Data, Java EE or whatever these are called in the Ruby, PHP, JavaScript etc. worlds. We can even be more happy when we work in places that gives us time to get things right. Either using frameworks correctly or add the custom bells and whistles needed.

Feel free to rant about all the stuff you want. But rant about actual bugs and inefficiencies and don’t start from a patronizing analogy.

Featured image: unsplash-logoDilyara Garifullina

| Comments (0) »

13-Jul-19


Never not learning…

Sometimes my teammate Gerrit teases me “Don’t you know this and that as a Java Champion?”… Of course I don’t. Honestly, the older I get, the better I know that I know nothing.

This week has been interesting. At first, I stumbled upon something like this

A shortcut to System properties

public interface Stuff {
 
    String SOMETHING_ENABLED_KEY = "stuff.is.enabled";
    static boolean isSomethingEnabled() {
 
        return Boolean.getBoolean(SOMETHING_ENABLED_KEY);
    }
}

And I was like: “How the hell do I set SOMETHING_ENABLED_KEY too true?!”, only having Boolean#parseBoolean(String s) in mind, which “parses the string argument as a boolean.”

Boolean#getBoolean(String s) actually goes to the Systems properties and checks for the existence of a property named s as described in the docs: “Returns true if and only if the system property named by the argument exists and is equal to the string ‘true’.”

I honestly didn’t expect such a shortcut in a wrapper class. To my surprise, those exists for other wrappers like java.lang.Long, too.

See related twitter thread:

But, the week just got more interesting.

Things that are and aren’t enums (aka isEnum())

See this gist right here: EnumTests.java. To understand this, you have to know a bit more about EnumTypes.

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.

I guess many people stop reading there and don’t go further into the planet example.

Enums are very versatile things. They can work as strategies and are one of the easiest and actually safest to use singletons in Java. They can also implement interfaces. I use this here in ParameterConversion.java to encapsulate a strategy and providing one defined instance only. Joshua Bloch talks about this in Effective Java Third Edition in detail.

But anyway, that’s not the point. Instances of an enum (that is, one of the “constants”) can overwrite the enums methods. As soon as you do this, they are realised as an anonymous, inner class. And with it, asking for EnumType.ENUM_CONSTANT.class.isEnum() will return false.

Brian Goetz is totally right here, even though it’s embarrassing for me:

I could have asked “EnumType.class, are you an enum?” and that holds correctly true. The enum constants however doesn’t promise that. If you want to check wether a thing is an instance of an enum type, than just do this: EnumType.ENUM_CONSTANT instanceof Enum or if you have an object of unknown type, do this Enum.class.isAssignableFrom(aThing.getClass())

I learned so much from the answers to my tweet here, you should check them out:

Twitters UI messes the threading up a bit, so I highlight that one here, from Joseph Darcy:

This old Oracle Blog is a great read: So you want to change the Java Programming Language…

And now what?

On to the next week, onto more learning, more development. Don’t let titles or honours impress you too much. We all learn new stuff, even in old things, each day. And I do think that’s a very good thing.

Title photo: unsplash-logoKimberly Farmer

| Comments (1) »

05-Jul-19