2
votes

I'm starting with quarkus and my build native is too slow(More than one hour and got OutOfMemoryError). I deleted the quarkus <artifactId>quarkus-amazon-lambda</artifactId> dependency from pom.xml and the native build was take about 13 minutes but did not create the function.zip file.

Anyone knows why this dependency causes this slowly build ?

Quarkus Lambda Tutorial: https://quarkus.io/guides/amazon-lambda

My configuration:

  • iMac 2011 - i5 2.4Ghz - 16Gb ram - No SSD
  • GraalVM CE 19.3.1
  • Java 8
  • Maven 3.6.3
  • Docker engine memory set 10Gb

Build Command

mvn clean install -Pnative -Dnative-image.docker-build=true -Dquarkus.native.enable-jni=true
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.com.fwborges.alexa</groupId>
    <artifactId>skill-bus-locator</artifactId>
    <version>1.0</version>
    <properties>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <surefire-plugin.version>2.22.0</surefire-plugin.version>
        <maven.compiler.parameters>true</maven.compiler.parameters>
        <quarkus.version>1.5.1.Final</quarkus.version>
        <compiler-plugin.version>3.8.1</compiler-plugin.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.quarkus</groupId>
                <artifactId>quarkus-bom</artifactId>
                <version>${quarkus.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>

        <!-- AWS Lambda -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-lambda</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-test-amazon-lambda</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Database -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-validator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm-panache</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jdbc-mysql</artifactId>
        </dependency>

        <!-- Log -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.1</version>
        </dependency>

        <!-- Http Clients -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jsonb</artifactId>
        </dependency>

        <!-- Utils -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>

        <!-- AWS Alexa SDK -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-alexa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazon.alexa</groupId>
            <artifactId>ask-sdk</artifactId>
            <version>2.29.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>io.quarkus</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.quarkus</groupId>
                        <artifactId>quarkus-maven-plugin</artifactId>
                        <version>${quarkus.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>native-image</goal>
                                </goals>
                                <configuration>
                                    <enableHttpUrlHandler>true</enableHttpUrlHandler>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

Build logs:

[skill-bus-locator-lambda-1.0-runner:25]    classlist:  44,330.01 ms
[skill-bus-locator-lambda-1.0-runner:25]        (cap):   3,911.88 ms
[skill-bus-locator-lambda-1.0-runner:25]        setup:   9,214.88 ms
18:30:44,765 INFO  [org.hib.val.int.uti.Version] HV000001: Hibernate Validator 6.1.5.Final
18:30:45,188 INFO  [org.hib.Version] HHH000412: Hibernate ORM core version 5.4.16.Final
18:30:45,215 INFO  [org.hib.ann.com.Version] HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
18:30:45,322 INFO  [org.hib.dia.Dialect] HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
18:36:15,233 INFO  [org.jbo.threads] JBoss Threads version 3.1.1.Final
Exception in thread "native-image pid watcher" java.lang.OutOfMemoryError: Java heap space
[skill-bus-locator-lambda-1.0-runner:25]     analysis: 4,862,370.37 ms

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "mysql-cj-abandoned-connection-cleanup"

Thanks!!

1
Hi! You need that dependency to get a functional lambda with Quarkus. Now, I am not sure if you can create a native image using Alexa, so far it don't have an extension. So maybe you hit some issues. Now, I use quarkus with AWS lambdas basically on a daily basis and build a native image took some time; but not that much time (maybe 5 to 8 minutes in a mid 2015 mac book pro). Perhaps the CPU is the bottle neck.Gerardo Arroyo
Hi Gerardo! I'm sorry for the late. Quarkus is already available for native images using alexa, if you see my pom.xml, you'll notice the quarkus-amazon-alexa dependency. And you were right about CPU performance, I up my docker engine to 4 cpus cores, remove some dependencies and set 12Gb of memory and got 1 hour of build. Yes, it's still too much. But it works for now, I'll continue looking for the solution better than that.Felipe Borges
Hi Felipe! Wow, but 1 hour to build is a lot of time. Perhaps you can open a ticket with quarkus and get some hints.Gerardo Arroyo

1 Answers

0
votes

I am not an expert on AWS Lambdas ans Quarkus. However, I have worked on tuning Java based application servers for years and I have seen this on your log file.

18:36:15,233 INFO  [org.jbo.threads] JBoss Threads version 3.1.1.Final
Exception in thread "native-image pid watcher" java.lang.OutOfMemoryError: Java heap 
space

Thus, it looks like the deployment process is causing an Out of Memory (OOM) issue, which makes sense with the slowness because before getting the OOM error the garbage collector has spent several CPU cycles on doing its best to clean the heap.

Therefore, perhaps the application has a memory leak bug or your heap has not been configured properly.