DEV Community

Efim Smykov
Efim Smykov

Posted on

2

Using ArC outside Quarkus

What is ArC

ArC is build time oriented implementation of CDI 2.0 - Contexts and Dependency Injection specification. ArC created by Quarkus team and used for DI in Quarkus. In this topic we will try use it not in Quarkus application.

How to use it

Bean definition

Because ArC based on CDI, for defining beans we will use standard annotations @ApplicationScoped for defining bean and @Inject for injecting beans into each other. It will look something like this:


import javax.inject.Inject;
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class ServiceImpl implements Service {

    @Inject
    Service2 service2;

    @Override
    public void serve() {

    }

}
Enter fullscreen mode Exit fullscreen mode

Bean processing

Entry point for processing beans is BeanProcessor. It can be created via builder. And then we can use method process, which will resolve beans and generate resources for fast application startup.

Implementation

Maven plugin

We will be using ArC in Maven application. To modify build process we need to create plugin. We need to have access to application .class files and all compile and runtime dependencies. It looks something like this:

package com.nutrymaco.arc.maven.plugin;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

@Mojo(name = "build", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true)
public class BuildMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;

    @Override
    public void execute() {
            // build logic
    }

}
Enter fullscreen mode Exit fullscreen mode

Bean processing

BeanProcessor need index for all classes that needed our application. So we use Jandex for creating index of all classes.

Indexer indexer = new Indexer();

// add all .class files to index
indexJar(project.getArtifact().getFile(), indexer);

for (Artifact artifact : project.getArtifacts()) {
    indexJar(artifact.getFile(), indexer);
}

Index index = indexer.complete();
Enter fullscreen mode Exit fullscreen mode

Then we can create BeanProcessor

BeanProcessor.builder()
    .setApplicationIndex(index)
    .setComputingBeanArchiveIndex(index)
    .setImmutableBeanArchiveIndex(index)
    .setGenerateSources(true)
    .setOutput(new JarResourceOutput(generatedJarCreator))
    .setTransformUnproxyableClasses(true)
    .build();
Enter fullscreen mode Exit fullscreen mode

JarResourceOutput writes generated by ArC classes and service provider files into JAR

switch (resource.getType()) {
    case JAVA_CLASS:
        jar.addFile(
            target.resolve(resource.getName()) + ".class",
            resource.getData());
        break;
    case SERVICE_PROVIDER:
        jar.addFile(
            target.resolve("META-INF")
                  .resolve("services")
                  .resolve(resource.getName()).toString(),
            resource.getData());
        break;
    case JAVA_SOURCE:
        break;
}
Enter fullscreen mode Exit fullscreen mode

Runtime

In main class we should initialize container and then we can request for beans.

public class AppMain {
    public static void main(String[] args) {
        var container = Arc.initialize();
        var service = container.select(Service.class);
        service.serve();
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

As the result we add build time DI for our application. For that we created maven plugin in which we useBeanProcessor for processing bean definitions. Then in runtime we initialize container using Arc.initialize(). You can use it like this or use Quarkus to get more performance optimizations and features without extra actions like creating plugins.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay