How do I use an ajc build parameter inside an aspect?

吃可爱长大的小学妹 提交于 2019-12-02 04:27:27
kriegaex

I do not know any way to do what you want. Even if it was possible, the string values would still be the same if you unpacked the JAR and loaded the modified classes from the file system or repackaged/renamed the JAR. The solution would be static, not dynamic.

Anyway, how about putting information like that into a configuration file packaged into the JAR or maybe even right into the manifest file? Maven has capabilities to add information to the manifest and Java can read them during runtime. I have not thought it through, not to speak of trying to implement something like that, but maybe this is a way you can go.

Feel free to ask follow-up questions.


Update: You can avoid the manifest approach and try to directly determine the JAR file for each loaded class, see also this answer.

Utility class:

package de.scrum_master.util;

import java.net.URL;

public class ClassFileHelper {
    public static URL getClassURL(Class<?> clazz) {
        return clazz.getResource('/' + clazz.getName().replace('.', '/') + ".class");
    }

    public static String getJARFromURL(URL url) {
        if (!url.getProtocol().equals("jar"))
            return null;
        String fileName = url.getFile();
        fileName = fileName.substring(0, fileName.lastIndexOf('!'));
        fileName = fileName.substring(fileName.lastIndexOf('/') + 1);
        return fileName;
    }
}

Usage:

I tried this in a Java + AspectJ project in which the aspects are wrapped in a JAR file and the Java files are stored in a file system directory. I just added the following advice to an aspect within the JAR:

before() : execution(public static void main(..)) {
    try {
        Class<?>[] classes = { String.class, this.getClass(), Class.forName("com.BadReader") };
        for (Class<?> clazz : classes) {
            System.out.println(clazz);
            URL classURL = ClassFileHelper.getClassURL(clazz);
            System.out.println(classURL);
            System.out.println(ClassFileHelper.getJARFromURL(classURL));
            System.out.println();
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

As you can see, the array contains

  • a JRE bootstrap class (String),
  • the aspect class itself (this.getClass()),
  • a class from the Java project outside the JAR (Class.forName("com.BadReader")).

Console output:

class java.lang.String
jar:file:/C:/Programme/Java/jre7/lib/rt.jar!/java/lang/String.class
rt.jar

class com.SafeReaderAspect
jar:file:/C:/Users/Alexander/Documents/java-src/SO_AJ_ITD2StepCompilation_AspectJ/aspectLib.jar!/com/SafeReaderAspect.class
aspectLib.jar

class com.BadReader
file:/C:/Users/Alexander/Documents/java-src/SO_AJ_ITD2StepCompilation_Java/bin/com/BadReader.class
null

Is this what you want?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!