CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-arc

Build time CDI dependency injection framework for Quarkus applications with conditional bean support and context management

Pending
Overview
Eval results
Files

build-properties.mddocs/

Build Property Conditional Beans

Enable beans based on build-time configuration properties, allowing feature toggles and environment-specific configurations. These annotations evaluate property values during the build process to determine bean inclusion.

Capabilities

IfBuildProperty Annotation

Enables beans when build-time properties match specified values.

/**
 * When applied to a bean class or producer method (or field), the bean will only be enabled
 * if the Quarkus build time property matches the provided value.
 * By default, the bean is not enabled when the build time property is not defined at all, 
 * but this behavior is configurable via the enableIfMissing property.
 * This annotation is repeatable. A bean will only be enabled if all the conditions 
 * defined by the IfBuildProperty annotations are satisfied.
 */
@Repeatable(IfBuildProperty.List.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
public @interface IfBuildProperty {
    /**
     * Name of the build time property to check
     */
    String name();

    /**
     * Expected String value of the build time property (specified by name) if the bean is to be enabled
     */
    String stringValue();

    /**
     * Determines if the bean is to be enabled when the property name specified by name has not been specified at all
     */
    boolean enableIfMissing() default false;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
    @interface List {
        IfBuildProperty[] value();
    }
}

Usage Examples:

import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.IfBuildProperty;

// Enabled when feature.analytics property is set to "true"
@ApplicationScoped
@IfBuildProperty(name = "feature.analytics", stringValue = "true")
public class AnalyticsService {
    public void trackEvent(String event) {
        // Analytics implementation
    }
}

// Enabled when property is missing (not defined)
@ApplicationScoped
@IfBuildProperty(name = "feature.experimental", stringValue = "enabled", enableIfMissing = true)
public class ExperimentalFeature {
    public void experimentalOperation() {
        // Experimental feature enabled by default
    }
}

// Multiple conditions - both properties must match
@ApplicationScoped
@IfBuildProperty(name = "database.type", stringValue = "postgresql")
@IfBuildProperty(name = "database.ssl", stringValue = "true")
public class SecurePostgreSQLService {
    public void connectToSecureDatabase() {
        // PostgreSQL with SSL implementation
    }
}

UnlessBuildProperty Annotation

Enables beans when build-time properties do NOT match specified values (inverse of IfBuildProperty).

/**
 * When applied to a bean class or producer method (or field), the bean will only be enabled
 * if the Quarkus build time property does not match the provided value.
 * By default, the bean is not enabled when the build time property is not defined at all, 
 * but this behavior is configurable via the enableIfMissing property.
 * This annotation is repeatable. A bean will only be enabled if all the conditions 
 * defined by the UnlessBuildProperty annotations are satisfied.
 */
@Repeatable(UnlessBuildProperty.List.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
public @interface UnlessBuildProperty {
    /**
     * Name of the build time property to check
     */
    String name();

    /**
     * The bean is enabled if the build time property (specified by name) does not match this value.
     */
    String stringValue();

    /**
     * Determines if the bean is enabled when the property name specified by name has not been specified at all
     */
    boolean enableIfMissing() default false;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
    @interface List {
        UnlessBuildProperty[] value();
    }
}

Usage Examples:

import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.UnlessBuildProperty;

// Enabled when cache.enabled property is NOT set to "false"
@ApplicationScoped
@UnlessBuildProperty(name = "cache.enabled", stringValue = "false")
public class CacheService {
    public void cache(String key, Object value) {
        // Caching implementation
    }
}

// Enabled when debug.mode property is NOT set to "true"
@ApplicationScoped
@UnlessBuildProperty(name = "debug.mode", stringValue = "true")
public class ProductionOptimizedService {
    public void performOptimizedOperation() {
        // Production-optimized implementation
    }
}

// Enabled when missing property should enable the bean
@ApplicationScoped
@UnlessBuildProperty(name = "feature.disabled", stringValue = "true", enableIfMissing = true)
public class DefaultEnabledFeature {
    public void defaultBehavior() {
        // Enabled unless explicitly disabled
    }
}

Producer Method Usage

Both annotations work with producer methods for conditional bean creation.

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.arc.properties.UnlessBuildProperty;

@ApplicationScoped
public class StorageConfigProducer {
    
    @Produces
    @IfBuildProperty(name = "storage.type", stringValue = "s3")
    public StorageProvider s3StorageProvider() {
        return new S3StorageProvider();
    }
    
    @Produces
    @IfBuildProperty(name = "storage.type", stringValue = "local")
    public StorageProvider localStorageProvider() {
        return new LocalStorageProvider();
    }
    
    @Produces
    @UnlessBuildProperty(name = "storage.type", stringValue = "s3")
    @UnlessBuildProperty(name = "storage.type", stringValue = "local")
    public StorageProvider defaultStorageProvider() {
        return new DefaultStorageProvider();
    }
}

interface StorageProvider {
    void store(String key, byte[] data);
}

class S3StorageProvider implements StorageProvider {
    public void store(String key, byte[] data) {
        // S3 implementation
    }
}

class LocalStorageProvider implements StorageProvider {
    public void store(String key, byte[] data) {
        // Local file system implementation
    }
}

class DefaultStorageProvider implements StorageProvider {
    public void store(String key, byte[] data) {
        // Default implementation
    }
}

Complex Conditional Logic

Combine multiple conditions for sophisticated bean activation rules.

import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.properties.IfBuildProperty;
import io.quarkus.arc.properties.UnlessBuildProperty;

// Complex service that requires multiple conditions
@ApplicationScoped
@IfBuildProperty(name = "payment.provider", stringValue = "stripe")
@IfBuildProperty(name = "payment.webhooks", stringValue = "true")
@UnlessBuildProperty(name = "payment.test-mode", stringValue = "true")
public class ProductionStripeWebhookHandler {
    
    public void handleWebhook(String payload) {
        // Production Stripe webhook handling
    }
}

// Alternative implementation for different conditions
@ApplicationScoped
@IfBuildProperty(name = "payment.provider", stringValue = "stripe")
@IfBuildProperty(name = "payment.test-mode", stringValue = "true")
public class TestStripeWebhookHandler {
    
    public void handleWebhook(String payload) {
        // Test mode Stripe webhook handling
    }
}

Property Configuration

Build properties are configured through various sources:

Application Properties

# application.properties
feature.analytics=true
database.type=postgresql
database.ssl=true
cache.enabled=true
storage.type=s3
payment.provider=stripe
payment.webhooks=true
payment.test-mode=false

Environment-Specific Properties

# application-dev.properties
debug.mode=true
feature.experimental=enabled
payment.test-mode=true

# application-prod.properties
debug.mode=false
cache.enabled=true
payment.test-mode=false

System Properties and Environment Variables

# System properties
java -Dfeature.analytics=true -jar application.jar

# Environment variables
export FEATURE_ANALYTICS=true
export DATABASE_TYPE=postgresql

Common Patterns

Feature Flags

// Feature flag implementation
@ApplicationScoped
@IfBuildProperty(name = "features.new-ui", stringValue = "enabled")
public class NewUIRenderer implements UIRenderer {
    public String render() {
        return "New UI implementation";
    }
}

@ApplicationScoped
@UnlessBuildProperty(name = "features.new-ui", stringValue = "enabled")
public class LegacyUIRenderer implements UIRenderer {
    public String render() {
        return "Legacy UI implementation";
    }
}

Database Provider Selection

// Database-specific implementations
@ApplicationScoped
@IfBuildProperty(name = "quarkus.datasource.db-kind", stringValue = "postgresql")
public class PostgreSQLSpecificService {
    public void usePostgreSQLFeatures() {
        // PostgreSQL-specific functionality
    }
}

@ApplicationScoped
@IfBuildProperty(name = "quarkus.datasource.db-kind", stringValue = "mysql")
public class MySQLSpecificService {
    public void useMySQLFeatures() {
        // MySQL-specific functionality
    }
}

Integration Toggle

// External service integration toggle
@ApplicationScoped
@IfBuildProperty(name = "integrations.slack", stringValue = "true")
public class SlackNotificationService implements NotificationService {
    public void notify(String message) {
        // Slack integration
    }
}

@ApplicationScoped
@IfBuildProperty(name = "integrations.email", stringValue = "true")
public class EmailNotificationService implements NotificationService {
    public void notify(String message) {
        // Email integration
    }
}

@ApplicationScoped
@UnlessBuildProperty(name = "integrations.slack", stringValue = "true")
@UnlessBuildProperty(name = "integrations.email", stringValue = "true")
public class LoggingNotificationService implements NotificationService {
    public void notify(String message) {
        // Fallback logging implementation
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-arc

docs

bean-container.md

bean-invocation.md

build-profiles.md

build-properties.md

index.md

interceptor-integration.md

logger-injection.md

runtime-lookup.md

tile.json