SDK Documentation
Java SDK
Enterprise-grade SDK for Java 8+ with Spring Boot and Kotlin support
Java 8+
Compatibility
Maven
& Gradle
Reactive
Support
Installation
Maven
<dependency>
<groupId>dev.autonoma</groupId>
<artifactId>autonoma-sdk</artifactId>
<version>2.0.0</version>
</dependency>
Gradle
// Groovy DSL
implementation 'dev.autonoma:autonoma-sdk:2.0.0'
// Kotlin DSL
implementation("dev.autonoma:autonoma-sdk:2.0.0")
Spring Boot Starter
<dependency>
<groupId>dev.autonoma</groupId>
<artifactId>autonoma-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
Quick Start
Basic Usage
import dev.autonoma.sdk.Autonoma;
import dev.autonoma.sdk.AnalysisResult;
import dev.autonoma.sdk.Prediction;
public class Example {
public static void main(String[] args) {
// Initialize client
Autonoma autonoma = Autonoma.builder()
.apiKey(System.getenv("AUTONOMA_API_KEY"))
.environment("production")
.build();
// Start monitoring
autonoma.start();
// Analyze code
String content = Files.readString(Paths.get("App.java"));
AnalysisResult result = autonoma.analyze(
AnalyzeOptions.builder()
.file("App.java")
.content(content)
.build()
);
// Get predictions
List<Prediction> predictions = autonoma.getPredictions();
// Apply auto-fix
for (Prediction pred : predictions) {
if (pred.isAutoFixAvailable()) {
FixResult fixResult = autonoma.applyFix(pred.getId());
System.out.println("Fix applied: " + fixResult.isSuccess());
}
}
// Clean up
autonoma.close();
}
}
Spring Boot Integration
// application.yml
autonoma:
api-key: ${AUTONOMA_API_KEY}
environment: production
auto-fix:
enabled: true
confidence-threshold: 0.95
monitoring:
enabled: true
sample-rate: 1.0
// Main Application
@SpringBootApplication
@EnableAutonoma
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// Service
@Service
public class UserService {
@Autowired
private Autonoma autonoma;
@Monitored
public User createUser(UserDto dto) {
// Method is automatically monitored
return userRepository.save(convertToEntity(dto));
}
@AutoFix
public void processPayment(Payment payment) {
// Autonoma will automatically fix issues in this method
// when confidence is high enough
}
}
// Controller with automatic error handling
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
// Errors are automatically captured by Autonoma
return ResponseEntity.ok(userService.findById(id));
}
}
Kotlin Support
import dev.autonoma.sdk.autonoma
import kotlinx.coroutines.*
fun main() = runBlocking {
// DSL-style initialization
val autonoma = autonoma {
apiKey = System.getenv("AUTONOMA_API_KEY")
environment = "production"
autoFix {
enabled = true
confidenceThreshold = 0.95
}
}
// Coroutine support
val result = autonoma.analyzeAsync {
file = "App.kt"
content = File("App.kt").readText()
}
// Extension functions
val predictions = autonoma.predictions()
.filter { it.severity == Severity.CRITICAL }
.map { it.applyFixIfAvailable() }
// Flow support
autonoma.predictionFlow()
.filter { it.autoFixAvailable }
.collect { prediction ->
println("New prediction: ${prediction.message}")
}
}
// Data class support
data class CustomMetric(
val name: String,
val value: Double,
val tags: Map<String, String> = emptyMap()
)
// Extension function
suspend fun Prediction.applyFixIfAvailable(): FixResult? {
return if (autoFixAvailable) {
autonoma.applyFix(id)
} else null
}
Reactive Programming
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
public class ReactiveService {
private final ReactiveAutonoma autonoma;
// Analyze files reactively
public Flux<AnalysisResult> analyzeProject(String directory) {
return Flux.fromIterable(Files.list(Paths.get(directory)))
.filter(path -> path.toString().endsWith(".java"))
.flatMap(path ->
Mono.fromCallable(() -> Files.readString(path))
.flatMap(content -> autonoma.analyze(
AnalyzeOptions.builder()
.file(path.toString())
.content(content)
.build()
))
);
}
// Stream predictions
public Flux<Prediction> streamPredictions() {
return autonoma.getPredictionsFlux()
.filter(pred -> pred.getSeverity() == Severity.HIGH)
.doOnNext(pred -> log.info("High severity: {}", pred.getMessage()));
}
// WebFlux integration
@GetMapping(value = "/predictions/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Prediction>> streamToClient() {
return autonoma.getPredictionsFlux()
.map(prediction -> ServerSentEvent.<Prediction>builder()
.data(prediction)
.build());
}
}
Configuration Options
// Programmatic configuration
Autonoma autonoma = Autonoma.builder()
// Required
.apiKey("your-api-key")
// Environment
.environment(Environment.PRODUCTION)
// API Configuration
.baseUrl("https://api.autonoma.dev")
.connectTimeout(Duration.ofSeconds(10))
.readTimeout(Duration.ofSeconds(30))
.maxRetries(3)
.retryDelay(Duration.ofSeconds(1))
// Features
.autoFix(AutoFixConfig.builder()
.enabled(true)
.confidenceThreshold(0.95)
.requireApproval(false)
.excludePatterns(Arrays.asList("*Test.java", "*/generated/*"))
.maxFixesPerRun(10)
.build())
// Monitoring
.monitoring(MonitoringConfig.builder()
.captureErrors(true)
.capturePerformance(true)
.captureCustomMetrics(true)
.samplingRate(1.0)
.captureStackTraces(true)
.build())
// Security
.encryption(true)
.anonymization(AnonymizationConfig.builder()
.enabled(true)
.patterns(Arrays.asList(
Pattern.compile("password\\s*=\\s*["'].*?["']"),
Pattern.compile("apiKey\\s*=\\s*["'].*?["']")
))
.build())
// Performance
.batchSize(100)
.flushInterval(Duration.ofSeconds(5))
.threadPoolSize(4)
// Logging
.logger(LoggerFactory.getLogger("autonoma"))
.logLevel(LogLevel.INFO)
// Callbacks
.onPrediction(pred -> log.info("New prediction: {}", pred))
.onFix(fix -> log.info("Fix applied: {}", fix))
.onError(error -> log.error("Autonoma error", error))
.build();
// Spring Boot configuration (application.properties)
autonoma.api-key=${AUTONOMA_API_KEY}
autonoma.environment=production
autonoma.base-url=https://api.autonoma.dev
autonoma.auto-fix.enabled=true
autonoma.auto-fix.confidence-threshold=0.95
autonoma.monitoring.enabled=true
autonoma.monitoring.sample-rate=1.0
autonoma.security.encryption=true
autonoma.performance.batch-size=100
autonoma.performance.flush-interval=5s
Configuration Profiles
Support for multiple environments:
# application-dev.yml
autonoma:
environment: development
monitoring:
sample-rate: 0.1
# application-prod.yml
autonoma:
environment: production
monitoring:
sample-rate: 1.0
Builder Pattern
Fluent API for easy configuration:
Autonoma autonoma = Autonoma.builder()
.withDefaults()
.apiKey(getApiKey())
.enableAutoFix()
.build();
Core Methods
analyze(AnalyzeOptions options)
Analyze code for potential issues, performance problems, and security vulnerabilities.
// Single file analysis
AnalysisResult result = autonoma.analyze(
AnalyzeOptions.builder()
.file("UserService.java")
.content(fileContent)
.context(Map.of(
"framework", "spring",
"javaVersion", "11"
))
.build()
);
// Batch analysis
List<AnalysisResult> results = autonoma.analyzeBatch(
Arrays.asList(
AnalyzeOptions.builder().file("Service.java").content(content1).build(),
AnalyzeOptions.builder().file("Controller.java").content(content2).build()
)
);
// With specific rules
AnalysisResult result = autonoma.analyze(
AnalyzeOptions.builder()
.file("PaymentService.java")
.content(content)
.rules(Arrays.asList("security", "performance"))
.severityThreshold(Severity.MEDIUM)
.build()
);
// Async analysis
CompletableFuture<AnalysisResult> future = autonoma.analyzeAsync(options);
future.thenAccept(result -> {
System.out.printf("Found %d issues in %s%n",
result.getPredictions().size(),
result.getFile());
});
// Stream processing
Files.walk(Paths.get("src"))
.filter(path -> path.toString().endsWith(".java"))
.parallel()
.map(path -> autonoma.analyze(createOptions(path)))
.forEach(this::processResult);
getPredictions(PredictionFilters filters)
Retrieve predictions for your codebase with optional filtering.
// Get all predictions
List<Prediction> predictions = autonoma.getPredictions();
// Filter by severity and type
PredictionFilters filters = PredictionFilters.builder()
.severities(Arrays.asList(Severity.CRITICAL, Severity.HIGH))
.type("security")
.status(PredictionStatus.OPEN)
.build();
List<Prediction> filtered = autonoma.getPredictions(filters);
// With pagination
Page<Prediction> page = autonoma.getPredictionsPaged(
filters,
PageRequest.of(0, 50, Sort.by("severity").descending())
);
// Stream processing
autonoma.getPredictions().stream()
.filter(pred -> pred.getConfidence() > 0.9)
.filter(Prediction::isAutoFixAvailable)
.forEach(pred -> autonoma.applyFix(pred.getId()));
// Group by severity
Map<Severity, List<Prediction>> bySeverity =
autonoma.getPredictions().stream()
.collect(Collectors.groupingBy(Prediction::getSeverity));
applyFix(String predictionId, FixOptions options)
Apply an auto-fix for a specific prediction with validation and rollback support.
// Apply fix with default settings
FixResult result = autonoma.applyFix("pred_123abc");
// Apply with options
FixOptions options = FixOptions.builder()
.dryRun(true) // Preview changes
.createBackup(true) // Backup before applying
.runTests(true) // Run tests after fix
.testCommand("mvn test")
.autoCommit(false)
.commitMessage("fix: resolve SQL injection vulnerability")
.build();
FixResult result = autonoma.applyFix("pred_123abc", options);
// Handle result
if (result.isSuccess()) {
System.out.println("Fix applied successfully!");
System.out.printf("Files changed: %d%n", result.getFilesChanged().size());
System.out.printf("Lines modified: %d%n", result.getLinesModified());
// Review changes
result.getChanges().forEach(change -> {
System.out.printf(" %s: %s%n", change.getFile(), change.getDescription());
});
} else {
System.err.printf("Fix failed: %s%n", result.getError());
// Rollback if available
if (result.getRollbackId() != null) {
autonoma.rollback(result.getRollbackId());
}
}
// Batch fixes with transaction support
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
txTemplate.execute(status -> {
try {
List<String> predictionIds = getHighConfidencePredictions();
BatchFixResult batchResult = autonoma.applyFixes(
predictionIds,
BatchFixOptions.builder()
.stopOnError(true)
.parallel(false)
.build()
);
if (!batchResult.isAllSuccessful()) {
status.setRollbackOnly();
}
return batchResult;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
});
Monitoring Methods
Monitor application performance and errors in real-time.
// Start monitoring
autonoma.start();
// Capture exceptions
try {
riskyOperation();
} catch (Exception e) {
autonoma.captureException(e,
ErrorContext.builder()
.user(userId)
.tags(Map.of(
"component", "payment",
"version", "2.1.0"
))
.extra(Map.of(
"orderId", orderId,
"amount", amount
))
.build()
);
}
// Performance timing
try (Timer timer = autonoma.startTimer("database.query")) {
return jdbcTemplate.query(sql, rowMapper);
} // Timer automatically records duration
// Custom metrics
autonoma.metric("api.requests", 1,
MetricTags.of("endpoint", "/api/users", "method", "GET"));
autonoma.gauge("queue.size", queue.size());
autonoma.histogram("response.size", response.length());
// Annotation-based monitoring
@Timed("user.service.create")
@Counted("user.created")
public User createUser(UserDto dto) {
return userRepository.save(convertToEntity(dto));
}
// Method interceptor for automatic monitoring
@Bean
public MethodInterceptor autonomaInterceptor(Autonoma autonoma) {
return invocation -> {
String methodName = invocation.getMethod().getName();
try (Timer timer = autonoma.startTimer("method." + methodName)) {
return invocation.proceed();
} catch (Exception e) {
autonoma.captureException(e);
throw e;
}
};
}
Advanced Features
Custom Rules
// Define custom rule
@Rule("no-system-out")
public class NoSystemOutRule implements AutonomaRule {
@Override
public List<Issue> analyze(CompilationUnit cu) {
List<Issue> issues = new ArrayList<>();
cu.findAll(MethodCallExpr.class).stream()
.filter(call -> call.toString().startsWith("System.out"))
.forEach(call -> issues.add(
Issue.builder()
.severity(Severity.WARNING)
.message("Use logger instead of System.out")
.line(call.getBegin().get().line)
.fix(generateLoggerFix(call))
.build()
));
return issues;
}
}
// Register rules
autonoma.addRule(new NoSystemOutRule());
autonoma.addRuleSet(companyStandardsRuleSet);
// XML configuration
<autonoma-rules>
<rule id="sql-injection" severity="critical">
<pattern>Statement.*execute\(.*\+.*\)</pattern>
<message>Potential SQL injection</message>
</rule>
</autonoma-rules>
AspectJ Integration
@Aspect
@Component
public class AutonomaAspect {
@Autowired
private Autonoma autonoma;
@Around("@annotation(monitored)")
public Object monitor(ProceedingJoinPoint pjp,
Monitored monitored) throws Throwable {
String name = monitored.value().isEmpty()
? pjp.getSignature().getName()
: monitored.value();
try (Timer timer = autonoma.startTimer(name)) {
return pjp.proceed();
} catch (Exception e) {
autonoma.captureException(e);
throw e;
}
}
@AfterReturning(
pointcut = "@annotation(autoFix)",
returning = "result"
)
public void autoFix(JoinPoint jp,
AutoFix autoFix,
Object result) {
// Analyze method after execution
autonoma.analyzeMethod(
jp.getTarget().getClass(),
jp.getSignature().getName()
);
}
}
Testing Integration
// JUnit 5 Extension
@ExtendWith(AutonomaExtension.class)
class UserServiceTest {
@Test
@AnalyzeTest
void testCreateUser() {
// Test runs normally
User user = userService.createUser(dto);
assertNotNull(user.getId());
// Autonoma analyzes test and code under test
}
@ParameterizedTest
@AutonomaSource("test-cases.json")
void testWithAutonomaData(TestCase testCase) {
// Autonoma provides test data based on
// code analysis and coverage gaps
}
}
// Custom test rule
@TestRule
public AutonomaTestRule autonomaRule =
AutonomaTestRule.builder()
.failOnIssues(Severity.HIGH)
.autoFix(true)
.generateReport(true)
.build();
// Mockito integration
@Mock
private Autonoma mockAutonoma;
@Test
void testWithMock() {
when(mockAutonoma.analyze(any()))
.thenReturn(AnalysisResult.empty());
// Test your code
}
// Test containers
@Testcontainers
class IntegrationTest {
@Container
private static AutonomaContainer autonoma =
new AutonomaContainer("autonoma:latest")
.withApiKey("test-key");
}
Build Tool Plugins
<!-- Maven Plugin -->
<plugin>
<groupId>dev.autonoma</groupId>
<artifactId>autonoma-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<apiKey>${env.AUTONOMA_API_KEY}</apiKey>
<failOnSeverity>HIGH</failOnSeverity>
<autoFix>true</autoFix>
<excludes>
<exclude>**/generated/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>analyze</goal>
</goals>
</execution>
</executions>
</plugin>
// Gradle Plugin
plugins {
id 'dev.autonoma.gradle' version '2.0.0'
}
autonoma {
apiKey = System.getenv('AUTONOMA_API_KEY')
failOnSeverity = 'HIGH'
autoFix = true
excludes = ['**/generated/**']
}
// Custom task
task autonomaReport(type: AutonomaReportTask) {
outputDir = file('build/reports/autonoma')
format = 'html'
}
Microservices Support
Distributed Tracing
// Spring Cloud Sleuth integration
@Configuration
@EnableAutoConfiguration
public class AutonomaTracingConfig {
@Bean
public TracingCustomizer autonomaTracingCustomizer(Autonoma autonoma) {
return builder -> builder
.addSpanHandler(new AutonomaSpanHandler(autonoma))
.addSpanExporter(new AutonomaSpanExporter(autonoma));
}
}
// Service mesh support
@Component
public class AutonomaInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) {
// Add trace headers
request.getHeaders().add("X-Autonoma-Trace-Id",
autonoma.getCurrentTraceId());
try (Span span = autonoma.startSpan("http.client")) {
span.tag("http.method", request.getMethod().toString());
span.tag("http.url", request.getURI().toString());
ClientHttpResponse response = execution.execute(request, body);
span.tag("http.status", response.getStatusCode().value());
return response;
}
}
}
// Kafka integration
@Component
public class AutonomaKafkaListener {
@KafkaListener(topics = "orders")
@AutonomaTrace
public void processOrder(Order order,
@Header("autonoma-trace-id") String traceId) {
autonoma.continueTrace(traceId);
// Process order with tracing
}
}
// Circuit breaker integration
@Component
public class PaymentService {
@CircuitBreaker(name = "payment", fallbackMethod = "fallbackPayment")
@AutonomaMonitor
public PaymentResult processPayment(Payment payment) {
return externalPaymentService.process(payment);
}
public PaymentResult fallbackPayment(Payment payment, Exception e) {
autonoma.captureException(e, ErrorContext.builder()
.tags(Map.of("fallback", "true"))
.build());
return PaymentResult.failed("Service unavailable");
}
}
Error Handling
import dev.autonoma.sdk.exceptions.*;
try {
AnalysisResult result = autonoma.analyze(options);
} catch (RateLimitException e) {
// Rate limit exceeded
log.warn("Rate limit hit, retry after: {}", e.getRetryAfter());
Thread.sleep(e.getRetryAfter().toMillis());
// Retry operation
} catch (ApiException e) {
// API errors (4xx, 5xx)
if (e.getStatusCode() == 401) {
log.error("Invalid API key");
} else if (e.getStatusCode() == 403) {
log.error("Access forbidden: {}", e.getMessage());
} else {
log.error("API error {}: {}", e.getStatusCode(), e.getMessage());
}
} catch (ValidationException e) {
// Input validation errors
log.error("Validation failed for field '{}': {}",
e.getField(), e.getMessage());
e.getErrors().forEach(error ->
log.error(" - {}: {}", error.getField(), error.getMessage())
);
} catch (NetworkException e) {
// Network connectivity issues
log.error("Network error: {}", e.getMessage());
// Implement retry logic or fallback
} catch (AutonomaException e) {
// Generic Autonoma exception
log.error("Autonoma error: {}", e.getMessage(), e);
}
// Global exception handler
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(AutonomaException.class)
public ResponseEntity<ErrorResponse> handleAutonomaException(
AutonomaException e) {
autonoma.captureException(e);
return ResponseEntity.status(500)
.body(new ErrorResponse("Internal error occurred"));
}
}
// Retry template
RetryTemplate retryTemplate = RetryTemplate.builder()
.maxAttempts(3)
.exponentialBackoff(1000, 2, 10000)
.retryOn(NetworkException.class)
.retryOn(RateLimitException.class)
.build();
AnalysisResult result = retryTemplate.execute(context ->
autonoma.analyze(options)
);
Best Practices
Resource Management
- • Use try-with-resources for timers/spans
- • Configure appropriate thread pool sizes
- • Implement proper shutdown hooks
- • Monitor memory usage with large batches
Performance
- • Use async methods for non-blocking ops
- • Enable batching for bulk operations
- • Configure connection pooling properly
- • Use reactive streams for large datasets
Security
- • Never hardcode API keys
- • Use secure credential storage
- • Enable encryption for sensitive data
- • Regularly rotate API keys
CI/CD Integration
- • Add to build pipeline early
- • Configure quality gates
- • Enable automatic fixes for safe issues
- • Generate reports for tracking
Ready to Get Started?
Add Autonoma to your Java project and start improving code quality