Building a Maven based Spring Boot app with multiple app classes with main() methods

I have a Maven based Spring Boot project with 2 Application classes. One is my main Spring Boot app, the other is a standalone example app. When attempting to build with ‘mvn package’ I get this error:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.6.4:repackage (repackage) on project xample-client: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.6.4:repackage failed: Unable to find a single main class from the following candidates [kh.aprs.botexample.APRSISBotExampleApplication, kh.aprs.clientexample.APRSISClientExampleApplication]

The 2 apps listed are my 2 apps, but only APRSISBotExampleApplication is the one I want to get packaged, so I need to tell Maven which is the the main app. This is configured with the <start-class> property, configured in a properties section like this:

<properties>
 <start-class>your.package.YourApplication</start-class>
</properties>

This is described here.

Calculating elapsed minutes between LocalDateTime instances

There’s many ways to this, like getting epoch millis, calculating the difference and then converting back into the units you need. With java.time apis and java.time.temporal.ChronoUnit you can calculate the difference between 2 LocalDateTime instances easily in one step with:

long elapsedMins = ChronoUnit.MINUTES.between(start, end);

I was looking for a refresher on how to do this and found my own post from 3 years ago in a Google search here (funny when that happens).

Refresher: serverless framework local development workflow

It’s been a while since I’ve written any notes about the Serverless framework, so here’s a few notes as a refresher on typical steps I use for local development.

As a reminder to self, regions I typically deploy to are:

  • us-west-1 : SF
  • us-west-2: Oregon
  • eu-west-2: London

AWS regions are listed here.

To deploy:

serverless deploy --region eu-west-2

To invoke local:

serverless invoke local --function functionName

To invoke remotely:

serverless invoke --function functionName --region eu-west-2

To check logs from last invoke:

serverless logs --function functionName --region eu-west-2

Running MySQL in a Docker container on MacOS

It’s been a while since I’ve run MySQL server on my MacBook Pro (see past notes here , here and more here) and since I got my new M1 MBP I haven’t installed it yet. Rather than doing a native install, I want to run it as a Docker container so I can throw it away easily when I’m done.

Starting MySQL in a Container

From the MySQL Docker page, run:

docker run -p 3306:3306 --name mysql-springboot -e MYSQL_ROOT_PASSWORD=your-root-pass-here -d mysql

The important part here is -p to expose port 3306 in the container as 3306 on the host. This will allow you to connect to localhost:3306 locally to MySQL in the container as if it’s running locally.

Connecting with mysql shell locally

Connect with mysql shell as if the server is running locally:

mysqlsh -u root

and enter the password when prompted. Create a db and setup a user that you use from your app running locally:

create database example;
create user 'exampleuser' identified by 'examplepassword';
grant all on example.* to 'exampleuser'