Hot questions for Using AspectJ in hystrix

Question:

I have a REST client interface like this:

public interface NameSearchClient {
    @RequestLine("POST")
    @Headers("Content-Type: application/json")
    SearchResponse searchByName(NameSearchRequest request);

}

It gets implemented and set-up in a factory class like this:

@Component
public class NameClientFactory {
    public <T> T createFeignClient(Class<T> clientClass, String apiUrl) {
        return Feign.builder()
                .encoder(new GsonEncoder())
                .decoder(new GsonDecoder())
                .target(clientClass, apiUrl);
    }
}

I was wondering if it's possible to write an Aspect annotation that upon every call made by that client, executes some action (another HTTP call in my case) and adds a new header to the request? Is AspectJ the right tool for that?


Answer:

Create a bean that implements feign.RequestInterceptor and do your work in there:

@Component
public class FeignRequestInterceptor implements RequestInterceptor {
  @Override
  public void apply(RequestTemplate template) {
    // your code here
  }
}

See also this answer.

Question:

The HystrixCommandAspect bean is declared in the HystrixCircuitBreakerConfiguration class but I would like to use my own custom implementation of HystrixCommandAspect and inject a different bean.

Application:

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

Configuration:

@Configuration
public class HystrixConfiguration {
    @Bean
    @Primary
    public HystrixCommandAspect hystrixCommandAspect(){
        return new com.hystrix.HystrixCommandAspect();
    }
}

Custom HystrixCommandAspect:

package com.hystrix;

@Aspect
public class HystrixCommandAspect extends com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect {
...
}

However, when I use the annotation @EnableCircuitBreaker it uses the HystrixCircuitBreakerConfiguration and doesn't even load my own @Bean definition.


Answer:

I upgraded spring to the latest release and this fixed the problem. I also noticed in the logs that it said it was overriding the bean provided in HystrixCircuitBreakerConfiguration.

Question:

I am trying to use Hystrix in my Java Application, its a Non spring java application.

Used following Maven Dependencies in POM to enable Hystrix commands :

  <dependency>
      <groupId>com.netflix.hystrix</groupId>
      <artifactId>hystrix-javanica</artifactId>
      <version>1.5.8</version>
    </dependency>

    <dependency>
      <groupId>com.netflix.hystrix</groupId>
      <artifactId>hystrix-core</artifactId>
      <version>1.5.12</version>
    </dependency>

    <dependency>
      <groupId>com.netflix.rxjava</groupId>
      <artifactId>rxjava-core</artifactId>
      <version>0.20.7</version>
    </dependency>

Used following Dependencies to enable AspectJ :

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.8.7</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.7</version>
</dependency>

Created a aop.xml in META-INF with following configuration :

<aspectj>

  <aspects>
    <aspect name="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect" />
  </aspects>

  <weaver options="-verbose">
    <include within="*" />
  </weaver>
</aspectj>

Used Hystrix Command in my Service Class :

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;

@Component
@Service
public class TestHystrix 

    @HystrixCommand(commandKey = "testHystrix", threadPoolKey = "testHystrix", commandProperties = {
            @HystrixProperty(name = "hystrix.command.testHystrix.execution.isolation.thread.timeoutInMilliseconds", value = "30") }, threadPoolProperties = {
                    @HystrixProperty(name = "hystrix.threadpool.testHystrix.maximumSize", value = "3") })
public void  testHystrix() {

Added following JVM Argument :

-DWeavingMode=compile

But at both Junit testing and application Runtime, its resulting into following error :

java.lang.NoSuchMethodError: com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect.aspectOf()Lcom/netflix/hystrix/contrib/javanica/aop/aspectj/HystrixCommandAspect;

Please help.


Answer:

Before asking a question, you should first consult the manual of any tool you like to use. I am just quoting form there:

Aspect weaving

Javanica supports two weaving modes: compile and runtime. (...)

  • CTW. To use CTW mode you need to use specific jar version: hystrix-javanica-ctw-X.Y.Z. This jar is assembled with aspects compiled with using AJC compiler. If you will try to use regular hystrix-javanica-X.Y.Z with CTW then you get NoSuchMethodError aspectOf() at runtime from building with iajc. Also, you need to start your app with using java property: -DWeavingMode=compile. (...)

So maybe you want to switch your library.

BTW, if you use compile-time weaving (CTW), you should not need aop.xml because AspectJ only uses it for load-time weaving (LTW).