AWS Lambda com Java 25 e GraalVM

Usar Lambda com java já foi motivo de risos e muitos falariam que é loucura, porem desde que a compilação nativa se tornou realidade este cenário vem mudando desde o java 11 quando as primeiras compilações nativas existiram.

Mas desde o Java 17 tudo foi avançando de forma muito rápida e hoje com o Java 25 se tornou algo totalmente tangível e sem nenhuma perda ao comparar com Golang, python que sempre foram as primeiras escolhas quando o assunto era Lambda.

Claro que existem tradeoffs a serem considerados e algumas configurações extras, nem tudo são flores mas eu acredito que logo tudo será contornado e melhorado

Bora por a mão na massa então, crie um projeto novo em java com maven, aqui estou com o maven 3.9.12 e java 25, versão do graalvm é a 25 também.

    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>3.16.1</version>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sqs</artifactId>
            <version>2.41.20</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>url-connection-client</artifactId>
            <version>2.41.20</version>
        </dependency>
        <dependency>
            <groupId>tools.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>3.0.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.42</version>
        </dependency>
        <!-- Provide a simple SLF4J binding so the NOP logger warning goes away during tests/runtime -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.36</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

Acima são as dependências essenciais, abaixo vamos as configurações de build

<plugins>
...
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <version>0.11.4</version>
                <configuration>
                    <imageName>bootstrap</imageName>
                    <mainClass>br.com.tiagoiwamoto.awslambdasamples.sqs.SqsLambdaHandler</mainClass>
                </configuration>
            </plugin>
...
</plugins>

O plugin acima é essencial para que o maven entenda que ao gerar a imagem nativa seja com esse nome ‘bootstrap’

E a parte do Profiles, que é a mais importante, mas talvez a que vai levar mais tempo, pois dentro dela existe o buildArgs que você vai passando tudo que precisa ser inicializado em tempo de runtime ou no build do runtime e até mesmo configurações que deseja que seja incluido no processo do build do nativo, alem de apontar para arquivos de reflections,resources, aqui eu acredito ser a segunda parte mais chata a primeira é o reflections que vamos ver já já.

    <profiles>
        <profile>
            <id>native</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>0.11.4</version>
                        <executions>
                            <execution>
                                <id>build-native</id>
                                <goals>
                                    <goal>compile-no-fork</goal>
                                </goals>
                                <phase>package</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <mainClass>br.com.tiagoiwamoto.awslambdasamples.sqs.SqsLambdaHandler</mainClass>
                            <skipNativeTests>true</skipNativeTests>
                            <buildArgs>
                                ...
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

Se deu certo ao executar mvn clean package -Pnative você vai ver na pasta target 3 arquivos, sendo 2 deles os tradicionais .jar e um arquivo sem extensão que é o binario e com o nome informado no plugin do graalvm.

agora é executar seu binário e no meu caso coloquei só um ‘Starting Lambda’ para testar

    static void main() {
        log.info("Starting Lambda");
    }

Com isso podemos implementar nossa lambda.

Para a compilação nativa não importa até a data de hoje (15/02/2026) você colocar aqueles @Override por conta do RequestHandler, nem precisa extender a classe na verdade. Isso porque a compilação nativa chama sempre o metodo main() e a partir dai você precisa implementar.

Em um próximo post vou mostrar como implementar um lambda sendo acionado por um Aws SQS que é um fluxo super comum.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *