我需要知道方面中的.jar的名称,以便可以通过@DeclareParents使用它创建一个字符串字段。
我知道我可以将事情传递给AJC编译器,但实际上可以使用从方面传递的参数吗?最终结果应该是带有附加字段的类,其中包含我的.jar名称作为值。
更新: 建议测试。Gson.jar是类路径上的.jar
InputStream r = Gson.class.getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"); String x = getString(r); System.out.println(x);
输出:
Manifest-Version: 1.0 Name: org/aspectj/lang/ Specification-Title: AspectJ Runtime Classes Specification-Version: 1.7 Specification-Vendor: aspectj.org Implementation-Title: org.aspectj.tools Implementation-Version: 1.7.3 Implementation-Vendor: aspectj.org Bundle-Name: AspectJ Runtime Bundle-Version: 1.7.3 Bundle-Copyright: (C) Copyright 1999-2001 Xerox Corporation, 2002 Palo Alto Research Center, Incorporated (PARC), 2003-2009 Contributors. All Rights Reserved.
似乎一次只能有一个MANIFEST.MF资源,而AspectJ.jar恰好位于类路径的首位。
我不知道您要做什么。即使有可能,如果您解压缩JAR并从文件系统中加载修改后的类或将其重新打包/重命名,则字符串值仍将相同。解决方案将是静态的,而不是动态的。
无论如何,如何将这样的信息放入打包到JAR的配置文件中,甚至直接放入清单文件中?Maven具有将信息添加到清单的功能,Java可以在运行时读取它们。我还没有考虑周全,更不用说尝试实现类似的东西了,但是也许这是您可以采用的方法。
随时提出后续问题。
更新: 您可以避免使用清单方法,并尝试直接确定每个已加载类的JAR文件,另请参见此答案。
实用类:
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; } }
用法:
我在Java + AspectJ项目中进行了尝试,在该项目中,方面包装在JAR文件中,而Java文件存储在文件系统目录中。我只是在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(); } }
如您所见,该数组包含
String
this.getClass()
Class.forName("com.BadReader")
控制台输出:
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
这是你想要的吗?