I need to know the name of my .jar inside the aspect so I can create a string field with it via @DeclareParents.
I know I can pass things to the ajc compiler, but is it
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
String
),this.getClass()
),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?