Tuesday, December 20, 2016

Quick Tip To Prevent Your Caches From Exploding

There are many scenarios when you can benefit from caching commonly used objects in your application, especially in web and micro-service oriented environments. The most simple type of caching you can do in Java is probably to introduce a private HashMap that you query before calculating an object to make sure you don't do the job twice.

Here is an example of that:


public class PrimeService {

    private Map<Long, BigInteger> cache = new HashMap<>();
    
    public BigInteger getPrime(long minimum) {
        return cache.computeIfAbsent(minimum, 
            m -> BigInteger.valueOf(m).nextProbablePrime()
        );
    }
    
}

This is a quick solution to the problem, but sadly not very efficient. After a few months of people entering all kinds of crazy numbers into the service, we will have a very large HashMap that might cause us to run out of memory.

Here is a quick trick to solve that. Instead of using a HashMap, you can use a LinkedHashMap and simply override the method removeEldestEntry. That allows you to configure your own limit function to prevent the map from exploding.


public class PrimeService {

    public final static int CACHE_MAX_SIZE = 1_000;

    private Map<Long, BigInteger> cache = new LinkedHashMap<>() {
        @Override
        protected boolean removeEldestEntry(Map.Entry<ID, Boolean> eldest) {
            return size() > PrimeService.CACHE_MAX_SIZE;
        }
    };
    
    public BigInteger getPrime(long minimum) {
        return cache.computeIfAbsent(minimum, 
            m -> BigInteger.valueOf(m).nextProbablePrime()
        );
    }
    
}

We have now successfully limited the cache, preventing it from explosion. Old entries will be removed as new ones are added. It should be noted that this soluton works well in small applications, but for more advanced scenarious you might want to use an external caching solution instead. If you are interested in caching entries in a SQL database without writing tons of SQL code, I would recommend Speedment since it is lightweight and has a very fluent API.

Until next time!

Friday, December 9, 2016

Creating a REST API with Speedment and Spring

Happy Spring Wishes from Speedment and Crew

With the 4th release of Spring Boot, developing enterprise applications for the web have become so much easier. Something that still requires a lot of time on the developer's behalf is modelling an existing database in for an example Hibernate to get an object-oriented view of the data. In this tutorial we are going to explore how to use the open source tool Speedment together with Spring to generate entities, managers and controllers with the press of a button, enabling you to get started with the development so much faster.

About Speedment

Speedment is an open source java toolkit that makes it possible for a developer to rapidly generate all the glue required to communicate with a database. Using a graphical tool, you can connect to a database and generate java sources in seconds. Speedment is built in a modular fashion, just like Spring, making it easy to learn and use only the parts you are interested in. In this article we are going to use a plugin for Speedment to generate Spring controllers in addition to the standard files.

Step 1: Creating a New Spring Boot Project

Spring Boot consists of a number of templates that make it easy to get started with a new application. We are going to use one called “spring-boot-starter-web” to set the stage for our web application.

Begin by creating a new Maven Project and add the following to your “pom.xml”-file:



<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</version>
    </parent>
    
    <groupId>com.github.pyknic</groupId>
    <artifactId>speedment-spring-example</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <properties>
        <java.version>1.8</java.version>
        
        <speedment.version>3.0.1</speedment.version>
        <mysql.version>5.1.39</mysql.version>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            
            <plugin>
                <groupId>com.speedment</groupId>
                <artifactId>speedment-maven-plugin</artifactId>
                <version>${speedment.version}</version>
                
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.version}</version>
                    </dependency>
                    
                    <dependency>
                        <groupId>com.speedment.plugins</groupId>
                        <artifactId>spring-generator</artifactId>
                        <version>${speedment.version}</version>
                    </dependency>
                </dependencies>
                
                <configuration>
                    <components>                       
<component>com.speedment.plugins.spring.SpringGeneratorBundle</component>
                    </components>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    <dependencies>
        <dependency>
            <groupId>com.speedment</groupId>
            <artifactId>runtime</artifactId>
            <version>${speedment.version}</version>
            <type>pom</type>
        </dependency>
        
        <dependency>
            <groupId>com.speedment.plugins</groupId>
            <artifactId>spring-generator</artifactId>
            <version>${speedment.version}</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

This will configure your project as a Spring Boot application and tell it to use Speedment with the Spring Generator Plugin.

Step 2: Using Speedment to Generate Sources

Once the pom-file has been modified, a number of new Maven goals will be available in the IDE. Speedment can be used both graphically or from the command line. In this tutorial, we are going to use the UI. To start the Speedment Tool, execute the following Maven goal on the project:

mvn speedment:tool

A dialog will open that let you connect to a database. Once connected, you will see a window with an overview of the database on the left and various configuration options in the center. For this tutorial the default settings will suffice, so simply press “Generate” in the toolbar.

Screenshot of the Speedment Open Source Tool

If you switch back to the IDE you will see the new generated sources. You will notice that every class exists in two copies, one of them with the “Generated”-prefix. The reason for this is to allow modifications without the risk of overwriting your changes should you need to regenerate the sources at some point. Files with the “Generated”-prefix will always be overwritten and files without it will only be created once.

Step 3: Create a Main File

Speedment has generated a complete object-oriented model of the database, but we still need to create an entry point for the application. We will put this in the main package and call it Main.java.

Main.java

package com.github.pyknic.spring;

import com.speedment.common.logger.Level;
import com.speedment.common.logger.LoggerManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    
    public static void main(String... args) {
        SpringApplication.run(Main.class, args);
    }
}

If we start the application, Spring Boot will setup a self-contained web application with a generated controller for every table in the database. We can try it out by going to the following path in a browser:

http://localhost:8080/hare/

A JSON representation of the “hare” table in my database will now be returned.


[
    {"id":1, "name":"Harry", "color":"Gray", "age":3},
    {"id":2, "name":"Henrietta", "color":"White", "age":2},
    {"id":3, "name":"Henry", "color":"Black", "age":9}
]

Note #1: If you get an exception that says something in style of this...

There was an unexpected error (type=Internal Server Error, status=500). 
Could not write content: No value present (through reference chain: 
java.util.ArrayList[0]...

...it probably means that you have nullable columns in your database that Speedment chooses to implement as OptionalLong, OptionalInt etc. You can turn this feature off in the Speedment Tool by setting the "Nullable Implementation" field to WRAPPER instead of OPTIONAL for those columns.

Note #2: If you get an exception in the style of this...

java.sql.SQLException: Access denied for user 'root'@'localhost' 
(using password: YES)

...you will need to create an application.properties-file in the root of the project and add the authentication details for your database.

application.properties

jdbc.username=root
jdbc.password=password

Summary

In this article we have used Speedment and the Spring Generator plugin to automatically create a complete Spring Boot Application. Speedment has generated entities, managers and REST controllers for communicating with the database. If you want to know more about Speedment and how you can control the generated code, check out the many examples at the Speedment GitHub page!

Monday, November 21, 2016

Hack Speedment into Your Own Personal Code Generator

Spire and Duke dressed as Neo from Matrix

Speedment is an Open Source toolkit that can be used to generate Java entities and managers for communicating with a database. This is great if you need an Object Relational Mapping of the domain model, but in some cases, you might want to generate something completely different using your database as the template. In this article I am going to show you a hack that you can use to take over that code generator in Speedment and use it for your own personal purposes. At the end of the article we will have a completely blank code generator that we can program to do our bidding!

Background

Speedment is designed to operate as a plugin to Maven. By invoking various new Maven goals we can instruct Speedment to connect to a database, generate source code and also remove any generated files from our project. It also contains a graphical user interface that makes it easy to configure the generation job based on metadata collected from our database. Now, imagine all this information that we can collect from analyzing that metadata. We know what tables exist, we know of all the constraints they have and what types the individual columns have. There are probably millions of use-cases where we can benefit from automatically generating stuff from that metadata. Following the steps in this article, we can do all those things.

Screenshot of the Speedment User Interface

Step 1: Set Up a Regular Speedment Project

Create a new Maven Project and add the following to the pom.xml-file:

pom.xml

<properties>
    <speedment.version>3.0.1</speedment.version>
    <mysql.version>5.1.39</mysql.version>
</properties>


<dependencies>
    <dependency>
        <groupId>com.speedment</groupId>
        <artifactId>runtime</artifactId>
        <version>${speedment.version}</version>
        <type>pom</type>
    </dependency>
</dependencies>


<build>
    <plugins>
        <plugin>
            <groupId>com.speedment</groupId>
            <artifactId>speedment-maven-plugin</artifactId>
            <version>${speedment.version}</version>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

We have added Speedment as a runtime dependency and configured the Maven plugin to use the standard MySQL JDBC driver to connect to our database. Great! You now have access to a number of new Maven goals. For an example, if we wanted to launch the Speedment UI we could do that by running:


mvn speedment:tool

If we did that now, Speedment would launch in normal mode allowing us to connect to a database and from it generate entities and managers for communicating with that database using Java 8 streams. That is not what we want to do this time around. We want to hack it so that it does exactly what we need it to do. We therefore continue to modify the pom.

Step 2: Modify the Plugin Declaration

Speedment is built up in a modular fashion with different artifacts responsible for different tasks. All the pre-existing generator tasks are located in an artifact called "com.speedment.generator:generator-standard". That is where we are going to strike! By removing that artifact from the classpath we can prevent Speedment from generating anything we don’t want it to.

We modify the pom as follows:


...
<plugin>
    <groupId>com.speedment</groupId>
    <artifactId>speedment-maven-plugin</artifactId>
    <version>${speedment.version}</version>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
       
        <!-- Add this: -->
        <dependency>
            <groupId>com.speedment</groupId>
            <artifactId>tool</artifactId>
             <version>${speedment.version}</version>
             <type>pom</type>
             <exclusions>
                 <exclusion>
                     <groupId>com.speedment.generator</groupId>
                     <artifactId>generator-standard</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</plugin>
...

What is that? We exclude a dependency by adding one? How can that even work? Well, Speedment is designed to include as little code as possible unless it is explicitly needed by the application. The "com.speedment:tool-artifact" is a dependency to the maven plugin already, and by mentioning it in the <dependencies>-section of the maven plugin we can append settings to its configuration. In this case, we say that we want the plugin to have access to the tool except we don’t want the standard generator.

There is a problem here though. If we try and launch the speedment:tool goal, we will get an exception. The reason for this is that Speedment expects the standard translators to be on the classpath.

Here is where the second ugly hack comes in. In our project, we create a new package called com.speedment.generator.standard and in it define a new java file called StandardTranslatorBundle.java. As it turns out, that is the only file that Speedment really needs to work. We give it the following content:

StandardTranslatorBundle.java

package com.speedment.generator.standard;


import com.speedment.common.injector.InjectBundle;
import java.util.stream.Stream;


public final class StandardTranslatorBundle implements InjectBundle {
    @Override
    public Stream<Class<?>> injectables() {
        return Stream.empty();
    }
}

Next, we need to replace the excluded artifact with our own project so that the plugin never realizes that the files are missing. We return to the pom.xml-file and add our own project to the <dependencies>-section of the speedment-maven-plugin. The full pom file looks like this:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.github.pyknic</groupId>
  <artifactId>speedment-general-purpose</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>
    
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <speedment.version>3.0.1</speedment.version>
  </properties>
    
  <dependencies>
    <dependency>
      <groupId>com.speedment</groupId>
      <artifactId>runtime</artifactId>
      <version>${speedment.version}</version>
      <type>pom</type>
    </dependency>
  </dependencies>
    
  <build>
    <plugins>
      <plugin>
        <groupId>com.speedment</groupId>
        <artifactId>speedment-maven-plugin</artifactId>
        <version>${speedment.version}</version>
        <dependencies>
          <dependency>
            <groupId>com.speedment</groupId>
            <artifactId>tool</artifactId>
            <version>${speedment.version}</version>
            <type>pom</type>
            <exclusions>
              <exclusion>
                <groupId>com.speedment.generator</groupId>
                <artifactId>generator-standard</artifactId>
              </exclusion>
            </exclusions>
          </dependency>
          <dependency>
            <groupId>com.github.pyknic</groupId>
            <artifactId>speedment-general-purpose</artifactId>
            <version>1.0.0-SNAPSHOT</version>
          </dependency>   
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

If we now build our project and then run the goal speedment:tool, we should be able to launch the graphical user interface without problem. If we connect to the database and then press "Generate", nothing will happen at all! We have successfully hacked Speedment into doing absolutely nothing!

Step 3: Turn Speedment Into What You Want It To Be

Now when we have a fresh, clean Speedment, we can start turning it into the application we want it to be. We still have a powerful user interface where we can configure the code generation based on a database model. We have an expressive library of utilities and helper classes to work with generated code. And above all, we have a structure for analyzing the database metadata in an object-oriented fashion.

To learn more about how to write your own code generation templates and hook them into the platform, check out this article. You should also check out the Speedment GitHub page to learn how the existing generators work (the ones we just disabled) and maybe get some inspiration on how you can build your own.

Until next time, continue hacking!

Monday, November 14, 2016

Auto-Generate Optimized Java Class Specializations

Spire and Duke are playing with specialized geometric shapes

If you visited JavaOne this year you might have attended my presentation on “How to Generate Customized Java 8 Code from your Database”. In that talk I showcased how the Speedment Open Source toolkit is used to generate all kinds of Java code using a database as the domain model. One thing we didn’t have time to go into though is the fact that Speedment is not only making code generation easier, it is also itself made up by generated code. In this article I will show you have we set up Speedment to generate specialized versions of many classes to reduce the memory footprint of performance critical parts of the system.

Background

As you might know, Java has a number of built-in value types. These are bytes, shorts, integers, longs, floats, doubles, booleans and characters. Primitive value types are different from ordinary objects primarily in that they can be allocated directly on the memory stack, reducing the burden on the Garbage Collector. A problem with not inheriting from Object is that they can’t be put into collections or passed as parameters to methods that take object parameters without being wrapped. Typical wrapper classes are therefore “Integer”, “Double”, “Boolean” etc.

Wrapping a value type is not always a bad thing. The JIT (Just-In-Time) compiler is very good at optimizing away wrapper types if they can safely be replaced with primitive values, but that is not always possible. If this occur in a performance critical section of your code like in an inner loop, this can heavily impact the performance of the entire application.

That’s what happened to us when working on Speedment. We had special predicates and functions that contained metadata about their purpose. That metadata needed to be analyzed very rapidly inside an inner loop, but we was slowed down by the fact that most of this metadata was wrapped inside generic types so that they could be instantiated dynamically.

A common solution to this problem is to create a number of “specializations” of the classes that contain the wrapper types. The specializations are identical to the original class except that they use one of the primitive value types instead of a generic (object only) type. A good example of specializations are the various Stream interfaces that exist in Java 8. In addition to “Stream” we also have an “IntStream”, a “DoubleStream” and a “LongStream”. These specializations are more efficient for their particular value type since they don’t have to rely on wrapping types in objects.

The problem with specialization classes is that they add a lot of boilerplate to the system. Say that the parts that need to be optimized consist of 20 components. If you want to support all the 8 primitive variations that Java has you suddenly have 160 components. That is a lot of code to maintain. A better solution would be to generate all the extra classes.

Template Based Code Generation

The most common form of code generation in higher languages is template based. This means that you write a template file and then do keyword replacement to modify the text depending on what you are generating. Good examples of these are Maven Archetypes or Thymeleaf. A good template engine will have support for more advanced syntax like repeating sections, expressing conditions etc. If you want to generate specialization classes using a template engine you would replace all occurrences of “int”, “Integer”, “IntStream” with a particular keyword like “${primitive}”, “${wrapper}”, “${stream}” and then specify the dictionary of words to associate with each new value type.

Advantages of template based code generation is that it is easy to setup and easy to maintain. I think most programmers that read this could probably figure out how to write a template engine fairly easy. A disadvantage is that a templates are difficult to reuse. Say that you have a basic template for a specialized, but you want floating types to also have an additional method. You could solve this with a conditional statement, but if you want that extra method to also exist in other places, you will need to duplicate code. A typical example of code that often need to be duplicated is hashCode()-methods or toString(). This is where model based code generation is stronger.

Model Based Code Generation

In model based code generation, you build an abstract syntax tree over the code you want generated and then render that tree using a suitable renderer. The syntax tree can be mutated depending on the context that it is being used in, for an example by adding or removing methods to implement a certain interface. The main advantage of this is higher flexibility. You can dynamically take an existing model and manipulate which methods and fields to include. The downside is that model based code generation generally take a bit longer to set up.

Case Study: Speedment Field Generator

At Speedment, we developed a code generator called CodeGen that uses the model based approach to automatically generate field specializations for all the primitive value types. In total around 300 classes are generated on each build.

Speedment CodeGen uses an abstract syntax tree built around the basic concepts of object oriented design. You have classes, interfaces, fields, methods, constructors, etc that you use to build the domain model. Below the method level you still need to write templated code. To define a new main class, you would write:


import com.speedment.common.codegen.model.Class; // Not java.lang.Class

...

Class createMainClass() {
  return Class.of("Main")
    .public_().final_()
    .set(Javadoc.of("The main entry point of the application")
      .add(AUTHOR.setValue("Emil Forslund"))
      .add(SINCE.setValue("1.0.0"))
    )
    .add(Method.of("main", void.class)
      .public_().static_()
      .add(Field.of("args", String[].class))
      .add(
        "if (args.length == 0) " + block(
          "System.out.println(\"Hello, World!\");"
        ) + " else " + block(
          "System.out.format(\"Hi, %s!%n\", args[0]);"
        )
      )
    );
}

This would generate the following code:


/**
 * The main entry point of the application.
 * 
 * @author Emil Forslund
 * @since  1.0.0
 */
public final class Main {
  public static void main(String[] args) {
    if (args.length == 0) {
      System.out.println("Hello, World!");
    } else {
      System.out.format("Hi, %s!%n", args[0]);
    }
  }
}

The entire model doesn’t have to be generated at once. If we for an example want to generate a toString()-method automatically, we can define that as an individual method.


public void generateToString(File file) {
  file.add(Import.of(StringBuilder.class));
  file.getClasses().stream()
    .filter(HasFields.class::isInstance)
    .filter(HasMethods.class::isInstance)
    .map(c -> (HasFields & HasMethods) c)
    .forEach(clazz -> 
      clazz.add(Method.of("toString", void.class)
        .add(OVERRIDE)
        .public_()
        .add("return new StringBuilder()")
        .add(clazz.getFields().stream()
          .map(f -> ".append(\"" + f.getName() + "\")")
          .map(Formatting::indent)
          .toArray(String[]::new)
        )
        .add(indent(".toString();"))
      )
    );
}

Here you can see how the Trait Pattern is used to abstract away the underlying implementation from the logic. The code will work for Enum as well as Class since both implement both the traits “HasFields” and “HasMethods”.

Summary

In this article I have explained what specialization classes are and why they are sometimes necessary to improve performance in critical sections of an application. I have also showed you how Speedment use model based code generation to automatically produce specialization classes. If you are interested in generating code with these tools yourself, go ahead and check out the latest version of the generator at GitHub!

Monday, October 31, 2016

What’s New in Speedment 3.0

Spire standing in front of a sign that says Forest

If you have followed my blog you know that I have been involved in the open-source project Speedment for a while. During the summer and fall I have worked a lot with finishing up the next big 3.0.0 release of the toolkit. In this post I will showcase some of the cool new features we have built into the platform and also explain how you can get started!

New Module System

The biggest change from the previous version of Speedment, and the one that took us most time to get right, is the new module system. If you have been following the progress of the new JDK 9 project Jigsaw, you will recognize this subject. Previously, Speedment consisted of one big artifact called com.speedment:speedment. In addition to this, we had a few minor projects like the speedment-maven-plugin and speedment-archetypes that made the tool easier to use. There was several issues with this design. First, it was very tedious to develop in it since we often needed to rebuild the entire thing multiple times each day and every build could take minutes. It was also not very plugin-friendly since a plugin had to depend on the entire code base, even if it only modified a small group of classes.

In 3.0 however, com.speedment is actually a multi-module pom-project with a clear build order. Inside it are groups of artifacts, also realized as multi-module projects, that separate artifacts based on when they are needed. We now have the following artifact groups:

  1. common-parent contains artifacts that are mature, reusable in a number of situations and that doesn’t have any dependencies (except on our own lightweight logging framework). Here you will find some of the core utilities of Speedment like MapStream and CodeGen.
  2. runtime-parent contains artifacts that are required by the end-user during the runtime of their application. We wanted to separate these into their own group to make sure that the final jar of the user’s app has as small footprint as possible.
  3. generator-parent contains artifacts related to the code generation and database analyzation parts of Speedment. These classes doesn’t require a graphical environment which is useful if you want to use Speedment as a general purpose code generator in a non-graphical environment.
  4. tool-parent contains all the artifacts used by the graphical Speedment tool. Here we put all our home-brewed JavaFX-components as well as resources like icons used by the UI.
  5. build-parent is a meta group that contains various artifacts that we build simply to make Speedment easier to use for the end user. Here we for an example have a number of shaded artifacts that you can use when you deploy your application on a server and the Maven Plugin that users use to launch Speedment as a Maven goal.
  6. plugins-parent is a whole new group where we put official plugins for Speedment that doesn’t quite fit into the general framework but that many users request. This makes it possible for us to automatically rebuild them in the general build cycle, making sure they are always up-to-date with the latest changes in the platform.
  7. archetypes-parent is a group of all the official Maven Archetypes for Speedment. This was previously a separate project but has now been lifted into the main project so that they can be automatically reinstalled every time Speedment is built.

All these groups are built in the same order as specified above. This makes it much easier to keep dependencies single-directional and the overall design of the system more comprehensive.

So how do I use it?

The beautiful thing is that you barely have to change a thing! We automatically build an artifact that is called com.speedment:runtime that you can depend on in your project. It contains transitive dependencies to the exact set of artifacts that are required to run Speedment.


<dependency>
    <groupId>com.speedment</groupId>
    <artifactId>runtime</artifactId>
    <version>3.0.1</version>
    <type>pom</type>
</dependency>

When it is time for deployment, you simply replace this dependency with com.speedment:runtime-deploy and you will get a shaded jar with all the Speedment-stuff bundled together and ready to ship!


<dependency>
    <groupId>com.speedment</groupId>
    <artifactId>runtime-deploy</artifactId>
    <version>3.0.1</version>
</dependency>

For more details about the new release, go to this official GitHub page and fork it!