Open sorryya opened 6 years ago
Called function with @Loggable from another project, it works.
@sorryya Is this issue resolved? I am facing the similar issue. I am using in a Java 8 Springboot environment. The Logger logs are getting logged. However, @Loggable never works. Is there a solution to this. Please advise.
I use Java 8 + Springboot 1.4.7 + Lombok + home made AspectJ, working on a project with 691 classes, and sometimes it works, sometimes it doesn't. In some cases, changing the order of the annotations on my method made it work ; other times it didn't change anything. What is very confusing is that I have the problem only with jcabi annotations...
I really would like to know how to debug that, but I have no clue of how to do it.
I am also playing a bit around with this issue.
What I found out is that you have to apply the versions of aspectjrt / jcabi-aspects also to the maven plugin:
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aspects</artifactId>
<version>0.22.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.1</version>
</dependency>
</dependencies>
</plugin>
jcabi-maven-plugin 0.14.1 is causing an issue within m2e so I reverted it to 0.14.
If you don't set the dependency java 1.6 and an old jcabi version is used.
mvn clean package -X
I was also not able to make this running. Looking forward for some new infos here. 👍
The lib "jcabi-aspects" already draws the dependency to the lib "aspectjrt". So "jcabi-maven-plugin" shouldn't need to explicitly declare the "aspectjrt" dependency with it.
Hi @Maze-fr - thanks for the information. I changed my pom.xml like this:
<build>
<plugins>
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aspects</artifactId>
<version>0.22.6</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aspects</artifactId>
<version>0.22.6</version>
</dependency>
</dependencies>
mvn clean package output:
[INFO] --- jcabi-maven-plugin:0.14:ajc (default) @ xxx ---
[INFO] jcabi-aspects 0.22.6/3f0a1f7 started new daemon thread jcabi-loggable for watching of @Loggable annotated methods
[INFO] Created temp dir /Users/user/git/xxx/xxx/target/jcabi-ajc
[INFO] jcabi-aspects 0.22.6/3f0a1f7 started new daemon thread jcabi-cacheable-clean for automated cleaning of expired @Cacheable values
[INFO] jcabi-aspects 0.22.6/3f0a1f7 started new daemon thread jcabi-cacheable-update for async update of expired @Cacheable values
22 warnings
[INFO] ajc result: 624 file(s) processed, 0 pointcut(s) woven, 0 error(s), 0 warning(s)
Seems that somehow the span>@</spanLoggable(Loggable.DEBUG) are not discovered.
Yes, I have the same problem : it says that everything is scanned, but it finds no @Loggable
@Maze-fr try this:
@com.jcabi.aspects.Loggable(value=com.jcabi.aspects.Loggable.DEBUG)
There are several issues. One is that somehow the compiler doesn't use the right import in my case. That was the reason why the annotation wasn't detected. It imports something jdk.nashorn...Loggable. Glad to have JD installed 😄
The next issue is that the maven plugin doesn't show the right outputs.
I think this should investigated by the authors of this plugin.
I guess this is a compiler issue, because the import is not considered to be used.
There are to ways of fixing this:
Hope this helps.
I may have a clue...
As I was a little upset of not being able to log with @Loggable
, I made my own "loggable" aspect to log all the methods of all my controllers, services, repositories and components, of my entire application. Spring AOP provides a very easy way to do it, so I tried...
When doing that, I noticed that my @Aspect
didn't work at all.
It didn't log at all (same problem as with @Loggable
), because you need to make your @Aspect
be a @Component
(Spring AOP documentation).
But it created another problem, which is complex for me to explain in English, so I hope you will manage to understand.
Each component (whatever the annotation used to define it, excepted if it is also a @Aspect
) is proxied by Spring AOP when an AOP aspect has to be applied to it.
If that component is injected directly (meaning without an interface to define the injected field instead of the component class itself), then the application fails to boot with a ClassCastException
raised as the proxy object is an instance of proxy and not of the component class.
It needs the good flag to be activated in the AOP annotation : @EnableAspectJAutoProxy(proxyTargetClass = true)
.
It forces Spring to make aspect proxies extending your classes, instead of making that dirty proxy class thing.
Once that problem solved, my own "loggable" aspect works very well, and I log the same way we do with @Loggable
.
Based on that, I thought that I could solve my problem with @Loggable
and I tried to make a @bean
from MethodLogger
class, which is the @Aspect
class working with @Loggable
. In my @Configuration
class :
@Bean
public MethodLogger methodLogger() {
// return Aspects.aspectOf(MethodLogger.class);
// return MethodLogger.aspectOf();
return new MethodLogger();
}
But it doesn't work... it's not recognised as an aspect by Spring AOP. So I wanted to try another solution...
But I can't extend MethodLogger
class to make it be a @Component
because... MethodLogger
is final !
(Seriously, I never understood what is the point of doing a final class out of an utility class full of constants and static methods...)
Then... to make a try, I copied all the classes necessary (yes... they are package protected...), and by adding @Component
and adapting the aspect conditions, it worked !
But I don't like to clone code, so if you want to make @Loggable
work in Spring, you should do something like that :
/**
* The Class SpringMethodLogger makes {@link Loggable} working in Spring proxies.
*/
@Aspect
@Component
@NoArgsConstructor
public class SpringMethodLogger {
private static final MethodLogger METHOD_LOGGER = Optional.ofNullable(MethodLogger.aspectOf())
.orElse(new MethodLogger());
@Around("execution(public * (@com.jcabi.aspects.Loggable *).*(..))"
+ " && !execution(String *.toString())"
+ " && !execution(int *.hashCode())"
+ " && !execution(boolean *.canEqual(Object))"
+ " && !execution(boolean *.equals(Object))")
public Object wrapClass(final ProceedingJoinPoint point) throws Throwable {
return METHOD_LOGGER.wrapClass(point);
}
@Around("@annotation(com.jcabi.aspects.Loggable)")
public Object wrapMethod(final ProceedingJoinPoint point) throws Throwable {
return METHOD_LOGGER.wrapMethod(point);
}
}
If your @Loggable
annotations are only in @(Rest)Controller(Advice)
, @Service
, @Repository
or @Component
annotated classes, then you don't even need to weave with jcabi at compilation any more, Spring AOP will take care of weaving at boot.
Does not work on Sring Boot + Gradle and @Service
annotation from service layer.
pom.xml:
log4j.properties:
Problem: Run with Main in IntelliJ IDEA, logger.debug("mylog") logged correctly, but @Loggable logged nothing.