Thymeleaf Spring configuration class not found error

When configuring Thymeleaf for a Spring project, you need the  org.thymeleaf:thymeleaf-spring4 dependency that contains required libraries for Thymeleaf support in Spring 4.

This dependency will transitively load other dependencies as well. Among others, it loads the Thymeleaf dependency itself, for which as we will see, it is important to be in the correct version.

You can check out the dependencies of your Maven project by running the mvn dependency:tree command.

[INFO] \- org.thymeleaf:thymeleaf-spring4:jar:3.0.1.RELEASE:compile
[INFO]    +- org.thymeleaf:thymeleaf:jar:3.0.1.RELEASE:compile
[INFO]    |  +- org.attoparser:attoparser:jar:2.0.0.RELEASE:compile
[INFO]    |  \- org.unbescape:unbescape:jar:1.1.3.RELEASE:compile
[INFO]    \- org.slf4j:slf4j-api:jar:1.6.6:compilecons

This list of transitive dependencies actually contains the correct ones for the currently latest Thymeleaf for Spring 4. Note the 3.0.1.RELEASE version on the second line.

Confusing Maven by bringing in another Thymeleaf (without knowing…)

It can happen that if you also use some other dependency that loads the org.thymeleaf:thymeleaf, then there is a chance, that it will load an older version and overwrite the correct one. This happened in my case as well.

I used the Spring Platform BOM to get a whole lot of compatible dependency versions already set up in my project. However, the  org.thymeleaf:thymeleaf transitive dependency version coming from it caused a problem, because it was a much older version and did not contain all the necessary classes. The resulting dependency tree looked like this:

[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] \- org.thymeleaf:thymeleaf-spring4:jar:3.0.1.RELEASE:compile
[INFO]    +- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile
[INFO]    |  \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile
[INFO]    \- org.slf4j:slf4j-api:jar:1.7.21:compile

Note the old 2.1.5.RELEASE version for org.thymeleaf:thymeleaf.

This old version was missing some classes that are present in the latest, because the API have been changed in the new version. Namely AbstractConfigurableTemplateResolver and TemplateResolver. Because these were not defined, I got class not found errors when I was trying to build the project.

Solution

So, the Platform BOM is unfortunately referencing an older version of Thymeleaf, we have two ways we can go about solving this.

1. Override the version by specifying it

If you are using the Platform BOM as a parent of your POM, you can just add a property to ovverride the version number to the correct one, like this:

<thymeleaf.version>3.0.1.RELEASE</thymeleaf.version>

If you are using it as a dependency, in your dependencyManagement section like:

<dependency>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>2.0.7.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Then you have to add the Thymeleaf as a dependency as well to override the version:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>${thymeleaf.version}</version>
</dependency>

I think these solutions are a bit fragile so I would recommend the next option I show you.

2. Switch to a lighter weight option

If you look at the contents and parents of the Platform BOM, you can see that it brings in a whole lot of dependencies, and some of them with outdated versions. For example Spring is used with a version that is a couple of releases older than the current one.

As you can see this can cause problems.

I think the best way to solve this, is to remove the Spring Platfom BOM and instead use the lighter weight Spring Framework BOM. It only contains dependency versions for the Spring Framework itself, and it references the latest from each module.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-framework-bom</artifactId>
    <version>${spring.framework.bom.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

If you check it this way, the transitive dependency that caused the problem is not loaded.

Deeper look into the cause

If we take a look at where did this old dependency came from, it might be hard to find.

There is no sign of it in the Spring Platform BOM, however is you go up to it’s parent (org.springframework.boot:spring-boot-starter-parent), and then to it’s parent (org.springframework.boot:spring-boot-dependencies), there you can find this old Thymeleaf version.

You can check it out here if you would like.

So the takeaway from this, is if you are searching for a transitive dependency, always make sure to also check in the parent and it’s parent and so on.

Run embedded Tomcat 8 in Maven

The most common way to run your Java web app using Maven in an embedded container is the Tomcat Maven Plugin. However, the latest version of this plugin is for Tomcat 7 (last update released back in 2013).

Luckily there is another plugin that you can use, the Maven Cargo Plugin.

Here is an example working configuration that you can use with the plugin.

<plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <configuration>
        <container>
            <containerId>tomcat8x</containerId>
            <artifactInstaller>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat</artifactId>
                <version>${tomcat.version}</version>
            </artifactInstaller>
        </container>
        <configuration>
            <type>standalone</type>
            <home>
                ${project.build.directory}/apache-tomcat-${tomcat.version}
            </home>
            <properties>
                <cargo.servlet.port>8080</cargo.servlet.port>
                <cargo.logging>high</cargo.logging>
            </properties>
        </configuration>
        <deployables>
            <deployable>
                <groupId>${project.groupId}</groupId>
                <artifactId>${project.artifactId}</artifactId>
                <type>war</type>
                <properties>
                    <context>/myapp</context>
                </properties>
            </deployable>
        </deployables>
    </configuration>
</plugin>

You can run your project using Cargo by using the cargo:run goal of the plugin. This will download the specified tomcat version and deploy your app into it.

Please note the ${tomcat.version} property, which you need to define in your pom.xml.

How to set up remote debugging in IntelliJ IDEA for a Java web application that is run by Tomcat Maven plugin

In this tutorial I show you a quick and easy way to debug your Java web application that is run by the Tomcat Maven plugin. There are just two short steps to this. Let’s see them.

Set up debugging options for Maven

You have to supply the required properties to Maven, so IDEA can connect to you app white it is running. This can be done by setting the MAVEN_OPTS environment property to

-Xdebug -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n -Xmx4g -Xms4g -XX:MaxPermSize=1g

Note here, the value 4000. This is the port that we are using for remove debugging. When you start your app with the Maven Tomcat plugin, you should see something like this, that means, the app is listening for remote debugging connections:

...
Listening for transport dt_socket at address: 4000
...

Configuring remote debugging in IDEA

For this you have to add a new Debug configuration that can be done by selecting the Run -> Edit configurations menu item. Here click the plus sign, to add a new configuration and select Remote.

The new Remote debugging configuration is immediately created. You can give it a name, and set the port to 4000. Here is an image about how I set it up:

remote-debugging-idea

 

After you configured it, click OK, select the created configuration and start debugging with the green button that resembles a bug.

remote-debugging-idea2

You are all set. You can add breakpoints and debug your running app remotely.

What’s with the -Xnoagent -Djava.compiler=NONE options?

You may see that in some places the remote debugging configuration contains the

-Xnoagent -Djava.compiler=NONE

options as well. These options were only required for very old JVMs so you can forget about them now.

 

How to fix “Setup was unable to create a new system partition or locate an existing system partition” during Windows 10 install

I was recently trying to install Windows 10 on my laptop from a USB drive, and came across an issue, that proved to be quite hard to crack as most of the solutions that were available online did not help me. In this article I will provide a complete description about it, and how to solve it, so maybe other will waste less time with it.

The issue

I bought a new SSD drive (a Samsung 850 EVO 500 GB version), and I wanted to install a brand new Windows 10 on it from a pendrive.

I downloaded the tool from Microsoft that allows creating bootable USB drives or creating ISO files for installing Windows 10. I created a bootable pendrive with it.

I inserted the new SSD drive and the bootable pendrive, and started the installation process.

So fa so good…

I got past the language selection screen, and gave the product key. Then, when I was asked to select which partition I want to install windows on, I got stuck. I mean completely, I couldn’t get past the message saying “Setup was unable to create a new system partition or locate an existing system partition”. Like you can see on the picture.

windows-10-install-partition-issue

I started to look for help online. I read countless articles, and found a couple of different solutions. For some people, changing the boot order helped, or manually selecting the boot drive when the computer is starting up. But for me, nothing mattered, I kept getting the same message.

The reason

I am unsure about the exact reason of this happening, but it was connected to the fact that I am using a USB drive for installing, and maybe also to the fact that I was using a USB 3.0 drive with a 2.0 socket.

My theory is, that when I was on the partition selection screen, for some reason the Windows installer could not find my SSD drive, so it couldn’t create a partition on it, or select an existing one for installation. I am not sure how this happened, but I found a few other people mentioning that this might have been the reason.

The solution

In short, the solution was to get rid of the USB drive, and use the SSD drive itself as the installation media. For this, what I had to do is to copy the installation files over to the SSD, and start the installer from there, without using the pendrive.

However, without an operating system, this is not really straightforward, so let’s see the steps.

Create a partition

  1. When the setup launched, and you see the Windows Setup window, press Shift + F10 to open the command prompt. You can also use a longer way to open it: http://www.tenforums.com/tutorials/2880-command-prompt-boot-open-windows-10-a.html
  2. Run diskpart in the console. This will launch the diskpart app, that allows you the perform disk related operations.
  3. Run list disk. This will list your disks, find your main drive, and look at the number of it. Let’s say it is 0.
  4. Run select disk=0, to select that disk.
  5. Run create partition primary, to create a partition that will use the full size of your drive.
  6. Run list partition, to list the partitions on your selected disk.
  7. Here you can see what is the ID of the partition you need to select. (You can see it from it’s size and that it’s type is “primary”). Let’s suppose the ID we found is 1. We use this in the next step.
  8. Run select partition=1, to select the created partition.
  9. Run active, this will make this the active partition.
  10. Run format fs=ntfs quick, to format the drive as NTFS.
  11. Run assign, to assign a letter to the partition.
  12. Run list volume, and find the letter assigned to your main drive and your USB drive from the list. Let’s suppose, you main drive’s partition is C and your USB drive is D.
  13. Run exit, to exit from diskpart.

Now your drive is ready, but you still need to copy the installation files from your USB drive to your main drive.

Copy installation files

  1. Navigate to the USB drive: cd d:
  2. Copy over the files to your main drive: xcopy d: c: /e /h /k 
  3. Go to your main partition and into the boot folder
    1. cd c:
    2. cd boot
  4. Make your c: drive bootable: bootsect /nt60 c:

You are ready. Just restart your computer, remove the USB drive, and you can install windows from your main drive to your main drive.

After the installation finished, windows will boot and offer you to select between setup and starting windows. Of course, you want to start windows now, and don’t install it again.

Cleanup

To get rid of this selection screen and any leftover files:

  1. Start windows normally, and open a command prompt as Administrator.
  2. Run bcdedit to see the boot menu list. Find Windows Setup from the list, and copy it’s identifier.
  3. Run bcdedit /delete {identifier}
  4. Go to your main drive, and manually delete any leftover directories and files that were part of your installation USB drive.

You are done, enjoy your Windows 10!

Update (2017.02.06)

This issue has happened to me again on a different laptop. It was an HP G5 with 500 GB HDD. So probably we can rule out that the SSD might have been the culprit.

Using the steps describen in this post helped to solve the issue again.

How to list the effective settings of Maven

When you are using Maven, sometimes you need custom configuration in your Maven settings.xml file. However, if you are using multiple versions of Maven, or there are multiple settings.xml files existing at the same time, it can be hard to track down which settings file is actually used.

To help with this issue, there is the following command:

mvn help:effective-settings

It results in an XML displayed on the console. That XML contains the settings that are used by Maven.