Примечание: это доказательство реализации концепции, а не последняя вещь.NoSuchMethodError с AspectJ
У меня есть 3-й. и я хочу ограничить их использование звука, например. ограничить продолжительность и т. д. (невозможно с менеджером безопасности). Для этого я подумал о замене возврата AudioSystem.getLine() оболочкой. это тест-аспект:
@Aspect
public class MixerAspect {
@Around("execution(* javax.sound.sampled.AudioSystem.getLine(javax.sound.sampled.Line.Info))")
public Object getLineAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AspectJ");
pjp.getArgs();
Line ret = (Line) pjp.proceed();
return ret;
}
}
каждая надстройка имеет свой собственный загрузчик классов, и они, как правило, не разделяют объекты, так это то, что я придумал:
@Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
....
if (className.equals(AudioSystem.class.getName())) {
.....
byte[] array = buffer.toByteArray();
try {
if (mixed == null)
mixed = weaver.defineClass(className, array, new CodeSource(mixerAspect, (CodeSigner[]) null));
return mixed;
} catch (IOException e) {
throw new ClassNotFoundException("unable to define class", e);
}
это initlialization-код WeavingURLClassloader:
weaver = new WeavingURLClassLoaderHelper(new URL[0], parent);
weaver.addURL(aspects[0]);
родитель является загрузчиком классов с доступом к аспекту Mixer и аспектам URL-массив, единственный элемент которого является один указал на т он каталог, в котором MixerAspect находится в моей aop.xml:.
<aspectj>
<aspects>
<aspect name="org.intellimate.izou.security.replaced.MixerAspect"/>
</aspects>
<weaver options="-Xset:weaveJavaxPackages=true -verbose -showWeaveInfo -debug">
<!-- Weave types that are within the javax.* or org.aspectj.*
packages. Also weave all types in the foo package that do
not have the @NoWeave annotation. -->
<include within="javax.*"/>
<include within="org.intellimate.izou.security.replaced.*"/>
<include within="javax.sound.sampled.AudioSystem"/>
</weaver>
</aspectj>
это (относится) журнал:
....(no relevant log)
T[email protected]53aad5d5
[WeavingURLClassLoaderHelper] info AspectJ Weaver Version 1.8.5 built on Thursday Jan 29, 2015 at 01:03:58 GMT
[WeavingURLClassLoaderHelper] info register classloader ro.fortsoft.pf4j.IzouPluginClassLoader$WeavingURLClassLoaderHelper
[WeavingURLClassLoaderHelper] info using configuration /Users/LeanderK/IdeaProjects/Izou/target/classes/META-INF/aop.xml
[WeavingURLClassLoaderHelper] info register aspect org.intellimate.izou.security.replaced.MixerAspect
[WeavingURLClassLoaderHelper] info AspectJ Weaver Version 1.8.5 built on Thursday Jan 29, 2015 at 01:03:58 GMT
[WeavingURLClassLoaderHelper] info register classloader ro.fortsoft.pf4j.IzouPluginClassLoader$WeavingURLClassLoaderHelper
[WeavingURLClassLoaderHelper] info using configuration /Users/LeanderK/IdeaProjects/Izou/target/classes/META-INF/aop.xml
[WeavingURLClassLoaderHelper] info register aspect org.intellimate.izou.security.replaced.MixerAspect
...(no relevant log)
[WeavingURLClassLoaderHelper] debug weaving 'javax.sound.sampled.AudioSystem'
[WeavingURLClassLoaderHelper] weaveinfo Join point 'method-execution(javax.sound.sampled.Line javax.sound.sampled.AudioSystem.getLine(javax.sound.sampled.Line$Info))' in Type 'javax.sound.sampled.AudioSystem' (AudioSystem.java:410) advised by around advice from 'org.intellimate.izou.security.replaced.MixerAspect' (MixerAspect.class(from MixerAspect.java))
[WeavingURLClassLoaderHelper] debug generating class 'javax.sound.sampled.AudioSystem$AjcClosure1'
2015-05-24 20:12:13,945 FATAL [Thread-5] org.intellimate.izou.threadpool.ThreadPoolManager (ThreadPoolManager.java:59) - unable to provide callback for: org.intellimate.izou.addon.AddOnManager$$Lambda$19/[email protected]
java.util.concurrent.CompletionException: java.lang.NoSuchMethodError: org.intellimate.izou.security.replaced.MixerAspect.aspectOf()Lorg/intellimate/izou/security/replaced/MixerAspect;
at java.util.concurrent.CompletableFuture.internalComplete(CompletableFuture.java:205) [?:1.8.0_25]
at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:459) [?:1.8.0_25]
at java.util.concurrent.CompletableFuture$Async.run(CompletableFuture.java:428) [?:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_25]
at org.intellimate.izou.threadpool.ThreadPoolManager$LoggingThreadFactory$1.run(ThreadPoolManager.java:73) [classes/:?]
Caused by: java.lang.NoSuchMethodError: org.intellimate.izou.security.replaced.MixerAspect.aspectOf()Lorg/intellimate/izou/security/replaced/MixerAspect;
at javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:410) ~[?:1.8.0_25]
at leanderk.izou.playground.ExampleAddOn.prepare(ExampleAddOn.java:41) ~[?:?]
at org.intellimate.izou.sdk.addon.AddOn.register(AddOn.java:41) ~[?:?]
at org.intellimate.izou.addon.AddOnManager$$Lambda$19/970865974.run(Unknown Source) ~[?:?]
at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:454) ~[?:1.8.0_25]
... 4 more
, похоже, это не ткут, а почему? Я не знаю, что еще попробовать. У меня есть следующие зависимости:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
, чтобы еще более усложнить вещи, загрузчик классов в другом проекте с простым Maven зависимости для этого проекта. Есть ли какой-то aspectj-intitialization, которого я не хватает?
редактировать уточнить ответ: вы также должны определить аспект через WeavingURLClassloader, это мой (пример - его упрощенный) код, то же самое может быть применен для каждого класса, который вы хотите смешивать-в. В моем случае класс был уже загружен через систему-загрузчик, так что я должен был excplicitly позвонить определить (быть осторожными, одни и те же классы, загруженные из различных загрузчиков классов не то же самые!)
private Class mixer = null;
......
@Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
.....
else if (className.contains("MixerAspect")) {
InputStream is = this.getResourceAsStream(className.replace('.', '/') + ".class");
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
try {
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
} catch (IOException e) {
throw new ClassNotFoundException("unable to load class", e);
}
try {
buffer.flush();
} catch (IOException e) {
throw new ClassNotFoundException("unable to load class", e);
}
byte[] array = buffer.toByteArray();
URL mixerAspect = getResource("org/intellimate/izou/security/replaced/MixerAspect.class");
try {
if (mixer == null) {
mixer = weaver.defineClass(className, array, new CodeSource(mixerAspect, (Certificate[]) null));
}
return mixer;
} catch (IOException e) {
throw new ClassNotFoundException("unable to define class", e);
}
}
Я делаю 100% -ное время переплетения времени ... так происходит какое-то преобразование. Я не знаю, понимаю ли я это правильно ... если я переплетаю javax.sound.sampled.AudioSystem, делает org.intellimate.izou.security.replaced.MixerAspect меняет? – Leander
No MixerAspect не изменяется во время плетения любого * конкретного * типа, но недостаточно просто скомпилировать MixerAspect с javac, он должен пройти через ткача, чтобы получить добавленные методы поддержки. Если он не получит aspectOf(), то ни один рекомендуемый класс не сможет с ним поговорить. Как я уже сказал, вам либо нужно использовать ajc для создания MixerAspect, либо вам нужно передать его через ткача с другими вашими типами. Как только MixerAspect был дополнен ткачом (один раз), его можно использовать с любым другим тканым типом, все они будут называть aspectOf(). –
ОК, спасибо ... его работа! :) – Leander