Skip to main content
Version: Latest

AspectJ Usage Guide for Brobot

Overviewโ€‹

This guide explains how to use the AspectJ enhancements in the Brobot framework. AspectJ provides powerful cross-cutting features without modifying existing code, including error recovery, performance monitoring, visual feedback, and more.

Table of Contentsโ€‹

  1. Quick Start
  2. Available Aspects
  3. Examples
  4. Best Practices
  5. Troubleshooting

Quick Startโ€‹

1. Enable AspectJ in Your Applicationโ€‹

@SpringBootApplication
@EnableAspectJAutoProxy
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}

2. Add Configuration Propertiesโ€‹

Create or update application.properties:

# Enable core aspects
brobot.aspects.sikuli.enabled=true
brobot.aspects.action-lifecycle.enabled=true
brobot.aspects.performance.enabled=true
brobot.aspects.state-transition.enabled=true

# Enable optional aspects
brobot.aspects.error-recovery.enabled=true
brobot.aspects.dataset.enabled=true
brobot.aspects.multi-monitor.enabled=true
brobot.aspects.visual-feedback.enabled=true

3. Use Annotations (Optional)โ€‹

@Recoverable(maxRetries = 3, delay = 1000)
public ActionResult clickLoginButton() {
return action.perform(clickOptions, loginButton);
}

@Monitored(threshold = 5000, trackMemory = true)
@CollectData(category = "login_automation")
public void performLogin(String username, String password) {
// Your automation code
}

Available Aspectsโ€‹

1. SikuliInterceptionAspectโ€‹

Purpose: Intercepts all Sikuli method calls for error handling and mock mode.

Benefits:

  • Automatic error translation
  • Mock mode without code changes
  • Performance metrics for Sikuli operations

Configuration:

brobot.aspects.sikuli.enabled=true
brobot.aspects.sikuli.performance-warning-threshold=5000

2. ActionLifecycleAspectโ€‹

Purpose: Manages action execution lifecycle (pre/post tasks).

Benefits:

  • Automatic timing and logging
  • Screenshot capture
  • Pause point management

Configuration:

brobot.aspects.action-lifecycle.enabled=true
brobot.aspects.action-lifecycle.capture-before-screenshot=false
brobot.aspects.action-lifecycle.capture-after-screenshot=true
brobot.action.pre-pause=0
brobot.action.post-pause=0

3. PerformanceMonitoringAspectโ€‹

Purpose: Tracks performance metrics for all operations.

Benefits:

  • Method-level performance tracking
  • Automatic slow operation detection
  • Performance trend analysis

Configuration:

brobot.aspects.performance.enabled=true
brobot.aspects.performance.alert-threshold=10000
brobot.aspects.performance.report-interval=300

Using @Monitored:

@Monitored(threshold = 3000, tags = {"critical", "ui"})
public void criticalOperation() {
// Operation that should complete within 3 seconds
}

4. StateTransitionAspectโ€‹

Purpose: Tracks and visualizes state machine transitions.

Benefits:

  • State transition graph building
  • Success rate tracking
  • DOT file visualization generation

Configuration:

brobot.aspects.state-transition.enabled=true
brobot.aspects.state-transition.generate-visualizations=true
brobot.aspects.state-transition.visualization-dir=./state-visualizations

5. ErrorRecoveryAspectโ€‹

Purpose: Provides automatic retry logic with sophisticated policies.

Benefits:

  • Configurable retry strategies
  • Circuit breaker pattern
  • Fallback methods

Configuration:

brobot.aspects.error-recovery.enabled=true
brobot.aspects.error-recovery.default-retry-count=3
brobot.aspects.error-recovery.default-retry-delay=1000

Using @Recoverable:

@Recoverable(
maxRetries = 5,
delay = 2000,
backoff = 2.0,
retryOn = {NetworkException.class},
fallbackMethod = "loginFallback"
)
public boolean login(String username, String password) {
// Login logic that might fail
}

public boolean loginFallback(String username, String password) {
// Alternative login approach
}

6. DatasetCollectionAspectโ€‹

Purpose: Automatically collects datasets for ML training.

Benefits:

  • Automatic data capture
  • Configurable sampling
  • Multiple output formats

Configuration:

brobot.aspects.dataset.enabled=true
brobot.aspects.dataset.output-dir=./ml-datasets
brobot.aspects.dataset.batch-size=100

Using @CollectData:

@CollectData(
category = "button_clicks",
captureScreenshots = true,
samplingRate = 0.1,
labels = {"success", "ui_automation"}
)
public ActionResult clickButton(StateObject button) {
return action.perform(clickOptions, button);
}

7. MultiMonitorRoutingAspectโ€‹

Purpose: Routes actions to appropriate monitors in multi-monitor setups.

Benefits:

  • Automatic monitor selection
  • Load balancing
  • Failover support

Configuration:

brobot.aspects.multi-monitor.enabled=true
brobot.aspects.multi-monitor.default-monitor=0
brobot.aspects.multi-monitor.enable-load-balancing=true

8. VisualFeedbackAspectโ€‹

Purpose: Provides visual highlighting during automation execution.

Benefits:

  • Search region highlighting
  • Match visualization
  • Action flow display

Configuration:

brobot.aspects.visual-feedback.enabled=true
brobot.aspects.visual-feedback.highlight-duration=2
brobot.aspects.visual-feedback.highlight-color=YELLOW
brobot.aspects.visual-feedback.show-action-flow=true

Examplesโ€‹

Example 1: Resilient Login with Retryโ€‹

@Component
public class LoginAutomation {

@Autowired
private Action action;

@Recoverable(maxRetries = 3, delay = 2000, backoff = 1.5)
@Monitored(threshold = 10000, tags = {"login", "critical"})
@CollectData(category = "login_success_rate")
public boolean performLogin(String username, String password) {
// Find and click username field
ActionResult usernameResult = action.perform(
new ClickOptions(),
new ObjectCollection.Builder()
.withStateObjects(usernameField)
.build()
);

if (!usernameResult.isSuccess()) {
throw new RuntimeException("Username field not found");
}

// Type username
action.perform(new TypeOptions(username), emptyCollection);

// Similar for password and login button...

return true;
}
}
@Component
public class SearchAutomation {

@Monitored(
name = "ProductSearch",
threshold = 3000,
trackMemory = true,
tags = {"search", "performance-critical"}
)
public List<Match> findProducts(String productImage) {
FindOptions options = new FindOptions.Builder()
.setSimilarity(0.8)
.setSearchRegion(productArea)
.build();

ActionResult result = action.perform(options,
new ObjectCollection.Builder()
.withImages(productImage)
.build()
);

return result.getMatchList();
}
}

Example 3: Multi-Monitor Automationโ€‹

@Component
public class MultiMonitorDemo {

// This will automatically route to the appropriate monitor
public void demonstrateMultiMonitor() {
// Click on left monitor
ObjectCollection leftButton = new ObjectCollection.Builder()
.withStateObjects(buttonOnLeftMonitor)
.build();
action.perform(clickOptions, leftButton);

// Click on right monitor - aspect handles routing
ObjectCollection rightButton = new ObjectCollection.Builder()
.withStateObjects(buttonOnRightMonitor)
.build();
action.perform(clickOptions, rightButton);
}
}

Best Practicesโ€‹

1. Selective Aspect Usageโ€‹

Not all aspects need to be enabled. Choose based on your needs:

  • Development: Enable visual feedback and verbose logging
  • Testing: Enable performance monitoring and dataset collection
  • Production: Enable error recovery and minimal logging

2. Performance Considerationsโ€‹

# Production settings
brobot.aspects.performance.enabled=true
brobot.aspects.performance.report-interval=3600 # Report hourly
brobot.aspects.visual-feedback.enabled=false # Disable visual feedback
brobot.aspects.dataset.sampling-rate=0.01 # Sample only 1%

3. Error Recovery Patternsโ€‹

// Use specific exception types for better control
@Recoverable(
retryOn = {FindFailed.class, StaleElementException.class},
skipOn = {IllegalArgumentException.class},
strategy = RecoveryStrategy.EXPONENTIAL_BACKOFF
)
public void robustAutomation() {
// Your code
}

// Combine with circuit breaker for critical operations
@Recoverable(maxRetries = 5, timeout = 30000)
@Monitored(threshold = 5000)
public void criticalOperation() {
// Your code
}

4. Dataset Collection Strategyโ€‹

// Collect data only for successful operations
@CollectData(
category = "successful_clicks",
onlySuccess = true,
samplingRate = 0.2,
maxSamples = 10000
)
public ActionResult performClick(StateObject target) {
// Your code
}

Troubleshootingโ€‹

Aspects Not Workingโ€‹

  1. Check if AspectJ is enabled:

    @EnableAspectJAutoProxy  // Required on main class
  2. Verify aspect configuration:

    brobot.aspects.*.enabled=true
  3. Check logs for aspect initialization:

    grep "Aspect initialized" application.log

Performance Impactโ€‹

If you notice performance degradation:

  1. Disable verbose logging:

    logging.level.io.github.jspinak.brobot.aspects=WARN
  2. Reduce monitoring scope:

    brobot.aspects.performance.exclude-patterns=.*toString,.*hashCode
  3. Use sampling:

    @Monitored(samplingRate = 0.1)  // Monitor only 10% of calls

Memory Issuesโ€‹

For memory-intensive operations:

  1. Limit data collection:

    brobot.aspects.dataset.max-queue-size=100
    brobot.aspects.dataset.batch-size=20
  2. Disable memory tracking:

    brobot.aspects.performance.track-memory=false

Compile-Time Weavingโ€‹

For better performance, use compile-time weaving:

  1. Add AspectJ Maven plugin:

    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <configuration>
    <complianceLevel>21</complianceLevel>
    <source>21</source>
    <target>21</target>
    </configuration>
    <executions>
    <execution>
    <goals>
    <goal>compile</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
  2. Build with AspectJ compiler:

    mvn clean compile

Conclusionโ€‹

AspectJ integration in Brobot provides powerful cross-cutting features that enhance automation reliability, observability, and maintainability. By using these aspects appropriately, you can build more robust automation solutions with less code and better insights into system behavior.