标签: aspectj

AspectJ加载时间weaver没有检测到所有类

我在"aspectj"模式下使用Spring的声明式事务(@Transactional注释).它在大多数情况下都可以完全像它应该的那样工作,但对于其中一个它没有.我们可以称之为Lang(因为这就是它实际上所称的).

我已经能够确定加载时间织布机的问题.通过打开aop.xml中的debug和verbose日志记录,它列出了所有正在编织的类.Lang根本没有在日志中提到有问题的类.

然后我在顶部放置了一个断点Lang,导致Eclipse在Lang加载类时挂起线程.当LTW编织其他类时,这个断点被击中!所以我猜测它要么编织也要Lang失败并且不输出,或者其他一些类有一个引用强制它Lang在实际有机会编织它之前加载.

我不确定如何继续调试这个,因为我无法以较小的规模重现它.有关如何继续的任何建议?


更新:其他线索也欢迎.例如,LTW实际上如何运作?似乎有很多魔法发生.是否有任何选项可以从LTW获得更多的调试输出?我目前有:

<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
Run Code Online (Sandbox Code Playgroud)

我忘了汤姆之前提到它:弹簧剂被用来允许LTW,即InstrumentationLoadTimeWeaver.


根据Andy Clement的建议,我决定检查AspectJ变压器是否甚至通过了这门课程.我放了一个断点ClassPreProcessorAgent.transform(..),看起来这个Lang类甚至都没有到达那个方法,尽管它被与其他类(Jetty的WebAppClassLoader的一个实例)相同的类加载器加载.

然后我接着断了一个断点InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..).甚至没有一个被击中Lang.我相信应该为所有加载的类调用该方法,无论他们使用什么类加载器.这开始看起来像:

  1. 我的调试有问题.可能Lang在Eclipse报告时没有加载
  2. Java bug?牵强附会,但我想它确实发生了.

接下来的线索:我打开了-verbose:class,看起来好像Lang 过早加载 - 可能是在变压器添加到Instrumentation之前.奇怪的是,我的Eclipse断点没有捕获到这个加载.

这意味着Spring是新的嫌疑人.在ConfigurationClassPostProcessor负载类中似乎有一些处理来检查它们.这可能与我的问题有关.


这些行ConfigurationClassBeanDefinitionReader导致Lang类被读取:

else if (metadata.isAnnotated(Component.class.getName()) ||
        metadata.hasAnnotatedMethods(Bean.class.getName())) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

特别是对类的metadata.hasAnnotatedMethods()调用getDeclaredMethods(),它加载该类中所有方法的所有参数类.我猜这可能不是问题的结束,因为我认为这些类应该被卸载.JVM是否可以出于不可知的原因缓存类实例?

java aop aspectj spring-aop

13
推荐指数
1
解决办法
5983
查看次数

Aspectj:来自外部jar的拦截方法

我正在使用X.jar并添加到我的AspectJ项目(在eclipse中).我已经为X.jar中的方法myMethod()编写了切入点和建议.

但aspectj不拦截此方法调用.

我怎么能告诉aspectj拦截外部jar上的方法调用.或者它不可能吗?

谢谢

aspectj

13
推荐指数
1
解决办法
5824
查看次数

在开普勒的生命周期中没有涵盖的aspectj-maven-plugin

我刚刚下载了OEPE(Kepler)并安装了m2e和m2e-wtp连接器.我发现在这条路径下:首选项 - > Maven->生命周期映射 - >打开工作区生命周期映射数据有一个预先配置的xml文件,该文件说maven应该忽略AspectJ的编译目标,我认为这就是为什么AspectJ运行时库是未添加到项目中,因此eclipse不会将项目识别为AspectJ项目.

<?xml version="1.0" encoding="UTF-8"?>
<lifecycleMappingMetadata>
<pluginExecutions>
    <pluginExecution>
        <pluginExecutionFilter>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <versionRange>1.6</versionRange>
            <goals>
                <goal>compile</goal>
            </goals>
        </pluginExecutionFilter>
        <action>
            <ignore />
        </action>
    </pluginExecution>
</pluginExecutions>
Run Code Online (Sandbox Code Playgroud)

我在xml文件中注释掉了这些行并再次重新加载.现在IDE不会忽略生命周期中的AspectJ插件标记,但是pom文件抱怨它无法识别执行标记.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
</dependencies>
<configuration>
    <source>1.6</source>
    <target>1.6</target>
</configuration>
<executions>
    <execution>
        <goals>
            <goal>compile</goal>
        </goals>
    </execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

使用indigo,m2e-wtp能够识别<execution>aspectj插件的标签,并能够自动将AspectJ运行时库添加到项目中,尽管在开普勒中并非如此.(我认为m2e-wtp的工作是将一个AspectJ项目从pom中取出但不太确定.)

顺便说一句.我怎么能像Indigo那样让事情发挥作用?我知道我可以右键单击项目并将其转换为Aspect项目以解决问题,但我希望IDE和插件从pom文件中实现该项目需要AspectJ jar.任何的想法?

lifecycle aspectj maven eclipse-kepler

13
推荐指数
1
解决办法
1万
查看次数

Tomcat 8,Spring Boot,@ Configurable LoadTimeWeaving没有-javaagent?

我正在尝试设置@Configurable域对象(不是由spring容器管理).
我已经通过添加-javaagent:path/to/spring-instrument.jar作为JVM参数来完成这项工作但是我不能100%清楚这个-javaagent是否必须到位.我在Tomcat 8上运行它.我可能会误解文档,但似乎我可以使用另一种机制来实现这一点,特别是这一行:

不要定义TomcatInstrumentableClassLoader了对Tomcat 8.0高.相反,让Spring InstrumentableClassLoader通过TomcatLoadTimeWeaver策略自动使用Tomcat的新本机设施.

代码示例如下:

@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }   
    @Bean
    public MyService myService(){
        return new MyService();
    }
}
Run Code Online (Sandbox Code Playgroud)
@Configurable
public class MyDomainObject {

    @Autowired
    private MyService myService;

    public MyService getMyService(){
        return myService;
    }
}
Run Code Online (Sandbox Code Playgroud)
 public class MyService {
    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public void test(){
        log.info("test");
    }
}
Run Code Online (Sandbox Code Playgroud)

那么有没有办法在不指定-javaagent的情况下编织这些@Configrable对象?我有兴趣学习如何在将WAR作为WAR部署到独立Tomcat 8服务器和/或在作为'胖'jar启动时使用嵌入式Tomcat 8服务器时完成此操作. …

aspectj load-time-weaving tomcat8 spring-boot embedded-tomcat-8

13
推荐指数
1
解决办法
1197
查看次数

在Webservice中添加AspectJ

我有一个Java EE Web服务(REST),现在想使用AspectJ来创建一个规则,打印出每个传入的服务调用及其参数.

我刚刚阅读了本 教程并实现了以下代码:

的pom.xml

        <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.10</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.10</version>
    </dependency>

</dependencies>
<build>
  <plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
            <complianceLevel>1.8</complianceLevel>
            <source>1.8</source>
            <target>1.8</target>
            <showWeaveInfo>true</showWeaveInfo>
            <verbose>true</verbose>
            <Xlint>ignore</Xlint>
            <encoding>UTF-8 </encoding>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <!-- use this goal to weave all your main classes -->
                    <goal>compile</goal>
                    <!-- use this goal to weave all your test classes -->
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)

...并创建了一个Test.aj文件,带有一个Pointcut,它应该在调用getSignOfLife()后打印出一个teststring:

import de.jack.businesspartner.service.BusinessPartnerServiceImpl;
public aspect TestAspectJ {

    pointcut getSignOfLife() : 
      call(void BusinessPartnerServiceImpl.getSignOfLife());

    before() : …
Run Code Online (Sandbox Code Playgroud)

java web-services aspectj maven

13
推荐指数
2
解决办法
316
查看次数

Dropwizard Metric Annotations @Timed无效

我正在尝试使用@Timed(http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/annotation/package-summary.html)等注释自动将指标发布到我的MetricRegistry .

这不是开箱即用的.在搜索问题时,我发现了Codahale Metrics:在普通Java使用@Timed指标注释,其中提到了这个工作的唯一方法是使用aspectj.我将此添加到我的项目中,但仍未在MetricRegistry中看到我的指标.

这是我的pom文件.我添加了一个librato库,它加载了com.codahale.metrics:metrics-annotation.

<dependency>
  <groupId>io.astefanutti.metrics.aspectj</groupId>
  <artifactId>metrics-aspectj</artifactId>
  <version>${metrics-aspectj.version}</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.8.10</version>
</dependency>

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <configuration>
      <showWeaveInfo>true</showWeaveInfo>
      <source>1.8</source>
      <target>1.8</target>
      <complianceLevel>1.8</complianceLevel>
      <encoding>UTF-8</encoding>
      <verbose>true</verbose>
      <aspectLibraries>
        <aspectLibrary>
          <groupId>io.astefanutti.metrics.aspectj</groupId>
          <artifactId>metrics-aspectj</artifactId>
        </aspectLibrary>
      </aspectLibraries>
    </configuration>
    <executions>
      <execution>
        <phase>process-sources</phase>
        <goals>
          <goal>compile</goal>
          <goal>test-compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

<dependency>
  <groupId>com.librato.metrics</groupId>
  <artifactId>metrics-librato</artifactId>
  <version>${metrics-librato.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

这就是我尝试使用指标的方式

@Metrics(registry = "default") // this.metricRegistry is default
public class Foo {
    @Inject
    private MetricRegistry metricRegistry;
    ...

    @Metered(name = "meterName")
    public void bar() { …
Run Code Online (Sandbox Code Playgroud)

java aspectj java-8 dropwizard librato

13
推荐指数
1
解决办法
2624
查看次数

Spring的LoadTimeWeaver代理无法启动

我正在尝试使用Spring和AspectJ实现加载时间编织.据我所知,我已经正确配置了所有内容,但是当我尝试运行集成测试时,我不断收到错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1079)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:643)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:407)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.boku.risk.service.perisistence.PersistenceTestBase.setupBase(PersistenceTestBase.java:23)
    at com.boku.risk.service.dao.CountryLimitDaoTest.setup(CountryLimitDaoTest.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native …
Run Code Online (Sandbox Code Playgroud)

aop spring aspectj load-time-weaving

12
推荐指数
2
解决办法
2万
查看次数

OSGi WeavingHook示例

有没有人有使用OSGi 4.3+ Weaving Hook服务的例子?使用AspectJ,ASM,JavaAssist怎么样?有人在使用OSGi WeavingHooks吗?

OSGi Core 5.0.0第56.2节中的示例简单地省略了实际的编织,并说"最后的编织留给了读者".

我的目标是:

  1. 创建一个可以放在字段(基元或对象)上的注释(@MyAnnotation).
  2. 创建一个org.osgi.framework.hooks.weaving.WeavingHook来编织带有该注释的类
  3. 使用加载时编织在具有该注释的任何字段修改处切入
  4. 触发已修改字段的EventAdmin事件.
  5. 从WeavingHook动态更新捆绑线路,以连接到EventAdmin捆绑包.

我的问题主要是#3.

我目前正在尝试使用AspectJ WeavingAdaptor进行编织,但是我在使用方面库时遇到了问题,因为它期望构造函数中的java.net.URL [] aspectURLs是jar或目录它可以在文件系统上找到,而不是捆绑.另外,我不知道如何通过回调的处理由韦弗产生的任何新类acceptClass(字符串名称,字节[])的方法GeneratedClassHandler.

也许WeavingAdaptor不适合开始编织?或者也许我不应该使用AspectJ?

MyAnnotation.java

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
Run Code Online (Sandbox Code Playgroud)

MyWeavingHook.java

public class MyWeavingHook implements WeavingHook {

    public class MyWeavingClassloader implements WeavingClassLoader {

        private Bundle b;

        public MyWeavingClassLoader(Bundle b) {
            this.b = b;
        }

        void acceptClass(java.lang.String name, byte[] bytes) {
            //no way to get this back into the woven classes bundle classloader?
        } 

        URL[] getAspectURLs() …
Run Code Online (Sandbox Code Playgroud)

java aop osgi aspectj load-time-weaving

12
推荐指数
1
解决办法
3887
查看次数

Spring方面如何在内部工作?

Say Service调用需要应用日志方面(注释)的Dao类.我想知道方面实际上是如何应用的.

根据我在服务对象下注入DAO时的理解,spring发现有一些方面(在这种情况下是日志记录)是为DAO配置的,因此它会注入代理对象而不是实际的目标对象.现在,当对DAO中的任何方法进行实际调用时,代理应用方面,然后调用实际的目标对象.那是对的吗 ?另外我相信这叫做跑步编织.

另一方面,可以使用加载时间编织(使用javaagent配置)完成相同的操作,其中对需要应用方面的类执行字节代码操作.所以代理不会在这里出现.

如果我错了,请纠正我,因为这是所有弹簧模块的基础?

java spring aspectj spring-aop

12
推荐指数
1
解决办法
8169
查看次数

在自定义注释的Aspect中传递方法参数

我正在尝试使用类似的东西org.springframework.cache.annotation.Cacheable:

自定义注释:

@Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CheckEntity {
        String message() default "Check entity msg";
        String key() default "";
    }
Run Code Online (Sandbox Code Playgroud)

方面:

@Component
@Aspect
public class CheckEntityAspect {
    @Before("execution(* *.*(..)) && @annotation(checkEntity)")
    public void checkEntity(JoinPoint joinPoint, CheckEntitty checkEntity) {
        System.out.println("running entity check: " + joinPoint.getSignature().getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

服务:

@Service
@Transactional
public class EntityServiceImpl implements EntityService {

    @CheckEntity(key = "#id")
    public Entity getEntity(Long id) {
        return new Entity(id);
    }
}    
Run Code Online (Sandbox Code Playgroud)

我的IDE(IntelliJ)没有看到任何与key = "#id"使用有关的特殊情况,与使用Cacheable不同颜色而不是纯文本的类似用法相比.我提到IDE部分只是作为一个提示,如果有帮助,看起来IDE预先知道这些注释或它只是意识到我的例子中不存在的一些连接.

checkEntity.key中的值为"#id"而不是预期的数字.我尝试使用ExpressionParser但可能不是以正确的方式. …

spring annotations aspectj spring-el

12
推荐指数
2
解决办法
8081
查看次数