Error type referred to is not an annotation type

Java Web Android iOS Python Frameworks Spring Maven programming

1. Introduction

In this post, I would demo how to solve error Type referred to is not an annotation type when using Spring AOP.

2. Environment

  • SpringBoot 2
  • java 1.8+
  • AspectJ Tools 1.9.4

3. The POM

We only use the SpringBoot 2 and AspectJ 1.9.4 , the POM is as follows:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.9.4</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.0.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

4. The Code

We want to use Spring AOP to add logging ability to SpringBoot web controllers, the code is as follows:

The Controller:

package com.bswen.testspringaop.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @RequestMapping(value = "hello")
    public @ResponseBody String getHello() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello";
    }
}

You can see that, this controller just simply returns a string, the url is http://localhost:8080/hello

The Spring AOP Aspect:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyConrollerLogger {
    private static Logger logger = LoggerFactory.getLogger(MyConrollerLogger.class);

    @Around("@within(com.bswen.testspringaop.controllers.HelloController)") // we want HelloController to be instrumented
    public void logAround(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        Object retval = pjp.proceed();
        long end = System.nanoTime();
        String methodName = pjp.getSignature().getName();
        logger.info("Execution of " + methodName + " took " +
                TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
    }
}

Run the code, we got the error message:

2019-07-06 22:54:40.012  WARN 22494 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat': Initialization of bean failed; nested exception is **java.lang.IllegalArgumentException: error Type referred to is not an annotation type: com.bswen.testspringaop.controllers.HelloController**
2019-07-06 22:54:40.024  INFO 22494 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-07-06 22:54:40.039 ERROR 22494 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error Type referred to is not an annotation type: com.bswen.testspringaop.controllers.HelloController
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]

5.Why did this error happen?

we had this error because we misused the Within expression,according to spring aop documents, When we define the pointcut by using within, there are following usages examples:

  • any join point (method execution only in Spring AOP) within the service package:
    • within(com.xyz.service.*)
  • any join point (method execution only in Spring AOP) within the service package or a sub-package:
    • within(com.xyz.service..*)
  • any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:
    • @within(org.springframework.transaction.annotation.Transactional)

Here we used the Within like this:

  • @Around(“within(@com.bswen.testspringaop.controllers.HelloController *)”)

It would let spring to find the class with annotation @HelloController, and because no class is annoatated by it, so there is an error.

6.How to solve this problem?

We should change the pointcut expression to this:

@Around("within(com.bswen.testspringaop.controllers.*)")

This means any class under com.bswen.testspringaop.controllers package should be instrumented.

Run the code, we get this:

2019-07-06 23:29:09.443  INFO 22579 --- [nio-8080-exec-1] c.b.t.aspects.MyConrollerLogger          : Execution of getHello took 1007 ms

6. Summary

Be careful if you want to use Within in spring aop pointcut expressions.

Упомянутый тип ошибки не является типом аннотации:

Я получил следующий аспект

@Around("execution(public * (@DisabledForBlockedAccounts *).*(..))" + " && @annotation(denyForTeam)")
public Object translateExceptionsDenySelectedAccount(ProceedingJoinPoint pjp, Deny deny) throws Throwable
{
    Account account = (Account) pjp.getArgs()[0];
    Account selectedAccount = (Account) pjp.getArgs()[1];

    if (ArrayUtils.contains(deny.value(), account.getRole()))
    {

        if (account.getType().equals(Type.CHEF) && !selectedAccount.getType().equals(Type.CHEF))
        {
            throw new IllegalAccessException("");
        }
    }
    return pjp.proceed();
}

и эта аннотация:

@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface DenyForTeam
{

Role[] value();

}

Я получаю сообщение об ошибке: указанный тип ошибки не является типом аннотации: denyForTeam

Почему в DenyForTeam нет аннотации? Он отмечен @interface

Я решил свою проблему, явно указав пакет

изменить следующее

@Around("@annotation(SessionCheck)")
public Object checkSessionState(ProceedingJoinPoint joinPoint) throws Throwable {
    // code here 
}

в

@Around("@annotation(my.aop.annotation.SessionCheck)")
public Object checkSessionState(ProceedingJoinPoint joinPoint) throws Throwable {
    // code here
}

или поместите их в одну упаковку

ответ дан 12 мар ’19, в 07:03

Должен быть аргумент метода с именем denyForTeam, тип которого должен быть аннотацией DenyForTeam. @annotation — привязать аннотацию к одноименному аргументу метода.

@Around("execution(public * (@DisabledForBlockedAccounts *).*(..))" + " && @annotation(denyForTeam)")
public Object translateExceptionsDenySelectedAccount(ProceedingJoinPoint pjp, Deny deny, DenyForTeam denyForTeam) throws Throwable
{

Если вы не хотите, чтобы аннотация передавалась в качестве аргумента, включите @DenyForTeam (полностью квалифицированный) в выражение pointcut.

@Around("execution(@DenyForTeam public * (@DisabledForBlockedAccounts *).*(..))")
public Object translateExceptionsDenySelectedAccount(ProceedingJoinPoint pjp, Deny deny) throws Throwable
{

ответ дан 20 дек ’11, 11:12

Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками

spring
aop
spring-aop

or задайте свой вопрос.

I created a small project and played around AOP with Spring Native.

Sample Classes

Interface based service:

public interface HelloService {
    String hello();
}

public class HelloServiceImpl implements HelloService {
    public String hello() {
        return "Hello";
    }
}

Class based service:

public class HiService {
    public String hi() {
        return "Hi";
    }
}

Annotated class:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Greeter {
}

@Service
public class GreetingService {
    @Greeter
    public String greet() {
        return "Greeting";
    }
}

Aspect:

@Aspect
public class MyAspect {
    @Around(value = "execution(* com.example.demonativeaop.HelloService.*(..))")
    public String helloIntroduction(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed() + " (hello intercepted)";
    }
    @Around(value = "execution(* com.example.demonativeaop.HiService.*(..))")
    public String hiIntroduction(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed() + " (hi intercepted)";
    }
    @Around(value = "@annotation(com.example.demonativeaop.Greeter)")
    //    @Around(value = " within(com.example.demonativeaop..*) && @target(com.example.demonativeaop.Greeter)")
    public String greeterIntroduction(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed() + " (greeter intercepted)";
    }
}

Here are some of the findings and improvement ideas.

@Aspect class

MyAspect class is annotated with @Aspect.

Declared as @Bean

When MyAspect is declared as a @Bean:

    @Bean
    public MyAspect myAspect() {
        return new MyAspect();
    }

The reflect-config.json requires this entry.

  {
    "name": "com.example.demonativeaop.MyAspect",
    "allDeclaredMethods": true
  }

This is because methods in the @Aspect class define pointcuts, but usually they are not referenced by the application.
Those methods need to be retained to create AOP proxies.

Improvement idea

Automatically add hint when a bean with @Aspect is found.

Annotated as @Component

When MyAspect class is annotated with @Componenet, the component scan finds the bean.
In this case, no manual configuration is required.

@Aspect
@Component
public class MyAspect {
    ...
}

The generated reflect-config.json has this entry:

  {
    "name": "com.example.demonativeaop.MyAspect",
    "allDeclaredFields": true,
    "allDeclaredConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredClasses": true,
    "methods": [
      {
        "name": "<init>",
        "parameterTypes": []
      }
    ]
  }

Reference in AOP expression

For a pointcut expression execution(* com.example.demonativeaop.HiService.*(..)), the reflect-config.json requires this entry:

  {
    "name": "com.example.demonativeaop.HiService",
    "allDeclaredMethods": true
  }

Otherwise, this exception is thrown at runtime:

...
Caused by: java.lang.IllegalArgumentException: warning no match for this type name: com.example.demonativeaop.HiService [Xlint:invalidAbsoluteTypeName]
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:319) ~[na:na]
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:227) ~[na:na]
...

For annotation based pointcut, @annotation(com.example.demonativeaop.Greeter), it requires the annotation to be in reflect-config.json as well.

  {
    "name": "com.example.demonativeaop.Greeter",
    "allDeclaredMethods": true
  }

Without the entry, this error is thrown:

...
Caused by: java.lang.IllegalArgumentException: error Type referred to is not an annotation type: com$example$demonativeaop$Greeter
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:319) ~[na:na]
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:227) ~[na:na]
...

Improvement idea

It would be nice if AOT parses the AOP expression and figures out any classes that has reference to, then auto generate hints for them.

AOP Proxies

In spring-native, there are two phases for AOP proxies.

The first phase is at AOT.
For class based proxies, ConfigurationContributor and ProxyGenerator generate proxy classes with ByteBuddy(e.g. com.example.demonativeaop.HiService$$SpringProxy$7f5de2cd) and write class files under target/generated-sources/spring-aot/src/main/resources/../*.class.
Also, it adds the generated proxies to the reflect-config.json in order for runtime to read them.

The next phase is at runtime.
The Target_DefaultAopProxyFactory substitutes the AOP proxy creation.
For class based proxies, it uses BuildTimeAopProxy(ObjenesisBuildTimeAopProxy) which loads the ByteBuddy generated proxies and instantiate them.

To bridge these two phases, the ProxyConfiguration#getProxyClassName() method guarantees the same name is generated based on the advised interfaces.

Class based proxy:

The HiService is a class based proxy service.
In order to generate a proxy for this class at build time, this hint is required.

@AotProxyHint(targetClass=com.example.demonativeaop.HiService.class, proxyFeatures = ProxyBits.IS_STATIC)

The hint is read by ConfigurationContributor#generateBuildTimeClassProxies and generates ByteBuddy proxy classes.(e.g. com.example.demonativeaop.HiService$$SpringProxy$7f5de2cd)

Improvement Idea

Currently, the user needs to add @AotProxyHint to trigger the ByteBuddy proxy generation.
It would be nice if this is not required; so that, build time automatically detects class based proxies for AOP and generates/persists proxies.

Interface based proxy

The HelloService is interfaced based proxy service. (with HelloServiceImpl)

This uses JdkDynamicAopProxy to generate AOP proxy at runtime.

Since this is a regular dynamic proxy at runtime, proxy-config.json requires this entry.

  [
    "com.example.demonativeaop.HelloService",
    "org.springframework.aop.SpringProxy",
    "org.springframework.aop.framework.Advised",
    "org.springframework.core.DecoratingProxy"
  ]

Improvement idea

Since this proxy entry is infrastructure logic to generate dynamic proxy, it would be nice that AOT automatically adds this hint at build time.

Skip to navigation
Skip to main content

Red Hat Customer Portal

Infrastructure and Management

  • Red Hat Enterprise Linux

  • Red Hat Virtualization

  • Red Hat Identity Management

  • Red Hat Directory Server

  • Red Hat Certificate System

  • Red Hat Satellite

  • Red Hat Subscription Management

  • Red Hat Update Infrastructure

  • Red Hat Insights

  • Red Hat Ansible Automation Platform

Cloud Computing

  • Red Hat OpenShift

  • Red Hat CloudForms

  • Red Hat OpenStack Platform

  • Red Hat OpenShift Container Platform

  • Red Hat OpenShift Data Science

  • Red Hat OpenShift Online

  • Red Hat OpenShift Dedicated

  • Red Hat Advanced Cluster Security for Kubernetes

  • Red Hat Advanced Cluster Management for Kubernetes

  • Red Hat Quay

  • OpenShift Dev Spaces

  • Red Hat OpenShift Service on AWS

Storage

  • Red Hat Gluster Storage

  • Red Hat Hyperconverged Infrastructure

  • Red Hat Ceph Storage

  • Red Hat OpenShift Data Foundation

Runtimes

  • Red Hat Runtimes

  • Red Hat JBoss Enterprise Application Platform

  • Red Hat Data Grid

  • Red Hat JBoss Web Server

  • Red Hat Single Sign On

  • Red Hat support for Spring Boot

  • Red Hat build of Node.js

  • Red Hat build of Thorntail

  • Red Hat build of Eclipse Vert.x

  • Red Hat build of OpenJDK

  • Red Hat build of Quarkus

Integration and Automation

  • Red Hat Process Automation

  • Red Hat Process Automation Manager

  • Red Hat Decision Manager

All Products

  • Getting the following exception when trying to deploy Spring 3.1.2 application containing aspect annotation with parenthesis.
ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-5) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customBean': Injection of autowired dependencies failed;

...

Caused by: java.lang.IllegalArgumentException: error Type referred to is not an annotation type: abc$xyz$pqr$MyAspectClass
    at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301) 
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:207) 
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getFallbackPointcutExpression(AspectJExpressionPointcut.java:358) 
        ...
  • Getting java.lang.IllegalArgumentException: error Type referred to is not an annotation type while deploying a Spring application with a class having aspect annotation with parenthesis.

Environment

  • Red Hat JBoss Application Platform (EAP)

    • 6.x
  • Spring Framework

    • 3.1.2
    • 3.2.4

Subscriber exclusive content

A Red Hat subscription provides unlimited access to our knowledgebase, tools, and much more.

Current Customers and Partners

Log in for full access

Log In

Я новичок в АОП и AspectJ. Я пытаюсь написать собственную логику для пользовательской аннотации с типом элемента TYPE. Я также хочу использовать параметры в моей аннотации, чтобы написать собственную логику внутри метода around. Я получаю указанную ниже ошибку. Я пробовал читать несколько источников, и большинство из них связано с использованием @annotation. Мне трудно понять то же самое. Может кто-нибудь объяснить, почему следующий способ с @within не работал с каким-то ясным примером?

Аннотация (Slf4jTrace.java):

package io.ud.project.falcon.logging;

import io.ud.project.falcon.logging.generator.AbstractLogTraceIdGenerator;
import io.ud.project.falcon.logging.generator.DefaultLogTraceIdGenerator;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Slf4jTrace {

    String traceKey() default "traceId";

    Class<? extends AbstractLogTraceIdGenerator> traceValueGenerator() default DefaultLogTraceIdGenerator.class;

}

Компонент аспекта (Slf4jTraceAspect.java):

package io.ud.project.falcon.logging;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
@SuppressWarnings("unused")
@Slf4j
public class Slf4jTraceAspect {

    @Pointcut("execution(public * *(..))")
    public void publicOperation() {
        //Using this pointcut annotation for Around method.
    }

    @Around(value = "@within(slf4jTrace) && publicOperation()")
    public void logTrace(ProceedingJoinPoint joinPoint, Slf4jTrace slf4jTrace) throws Throwable {
        //Custom logic that uses slf4jTrace's parameters        
        joinPoint.proceed();
        //Custom logic that uses slf4jTrace's parameters
    }
}

Аннотированный класс (Foo.java):

package io.ud.project.falcon.logging;

import io.ud.project.falcon.logging.Slf4jTrace;

@Slf4jTrace(traceKey = "auditID")
public class Foo {

    public void doSomething() {
        //Something happens here.
    }

}

Ошибка при запуске приложения:

, 2021-01-02 22:16:41,340, ERROR [main] o.s.b.SpringApplication.reportFailure(833) | Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectMapperConfigurer' defined in springfox.documentation.spring.web.SpringfoxWebMvcConfiguration
: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.annotation.ProxyCachingConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error Type referred to is not an annotation type: slf4jTrace
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:497)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:238)
        at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:709)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)
        at io.ud.project.falcon.FalconApplication.main(FalconServiceApplication.java:65)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

Понравилась статья? Поделить с друзьями:
  • Error type int argument given to delete expected pointer
  • Error type in swift
  • Error type identifier expected
  • Error type excel на русском
  • Error type card removed