Spring AOP pointcut with "#target" not working because can't access current invocation - spring-aop

I'm trying to get a pointcut working.
This pointcut works:
#Around("execution(public * my.package..*ClassSuffix.*(..))")
But this pointcut does not:
#Around("execution(public * my.package..*ClassSuffix.*(..)) && !#target(my.package.NoLogging)")
The exception is
DEBUG o.s.aop.aspectj.AspectJExpressionPointcut - Could not access current invocation - matching with limited context: java.lang.IllegalStateException: No MethodInvocation found: Check that an AOP invocation is in progress, and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor!
DEBUG o.s.aop.aspectj.AspectJExpressionPointcut - Failed to evaluate join point for arguments [] - falling back to non-match
java.lang.NullPointerException: null
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.visit(ShadowMatchImpl.java:195)
at org.aspectj.weaver.ast.HasAnnotation.accept(HasAnnotation.java:31)
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.matches(ShadowMatchImpl.java:132)
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.visit(ShadowMatchImpl.java:163)
at org.aspectj.weaver.ast.Not.accept(Not.java:26)
at org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator.matches(ShadowMatchImpl.java:132)
at org.aspectj.weaver.reflect.ShadowMatchImpl.matchesJoinPoint(ShadowMatchImpl.java:87)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:357)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at my.package.FooClassSuffix$$EnhancerBySpringCGLIB$$e7bc07ac.doSomething(<generated>)
So it seems that the more complex pointcut requires some context, and ExposeInvocationInterceptor#invoke(..) is called at some point, but not at the right point because ExposeInvocationInterceptor#currentInvocation() throws an exception?
Is there something wrong with the pointcut? I used this as a reference: https://stackoverflow.com/a/38866088/361414
Pointcuts are defined in a class with these annotations:
#Aspect
#Component
#Order(20)

Related

Strange transactional id errors when using the kafka sink

I had a Flink 1.15.1 job configured with
execution.checkpointing.mode='EXACTLY_ONCE'
that was failing with the following error
Sink: Committer (2/2)#732 (36640a337c6ccdc733d176b18adab979) switched from INITIALIZING to FAILED with failure cause: java.lang.IllegalStateException: Failed to commit KafkaCommittable{producerId=4521984, epoch=0, transactionalId=}
...
Caused by: org.apache.kafka.common.config.ConfigException: Invalid value for configuration transactional.id: String must be non-empty
that happened after the first checkpoint was triggered. The strange thing about it is that the KafkaSinkBuilder was used without calling setDeliverGuarantee, and hence the default delivery guarantee was expected to be used, which is NONE 1.
Is that even possible to start with? Shouldn't kafka transactions be involved only when one follows this recipe in 2?
* <p>One can also configure different {#link DeliveryGuarantee} by using {#link
* #setDeliverGuarantee(DeliveryGuarantee)} but keep in mind when using {#link
* DeliveryGuarantee#EXACTLY_ONCE} one must set the transactionalIdPrefix {#link
* #setTransactionalIdPrefix(String)}.
So, in my case, without calling setDeliverGuarantee (nor setTransactionalIdPrefix), I cannot understand why I was seeing these errors. To avoid the problem, I temporarily relaxed the checkpointing settings to
execution.checkpointing.mode='AT_LEAST_ONCE'
but I'd like to understand what was happening.
Like the JavaDoc mentions, if you enable exactly-once, you must set a transactionalIdPrefix. A complete recipe on how-to configure exactly-once with Apache Kafka can be found in this recipe: https://www.docs.immerok.cloud/docs/cookbook/exactly-once-with-apache-kafka-and-apache-flink/
Disclaimer: I work for Immerok

OptaPlanner benchmarking won't run

I'm trying to run an OptaPlanner benchmark with the following configuration:
<?xml version="1.0" encoding="UTF-8"?>
<plannerBenchmark xmlns="https://www.optaplanner.org/xsd/benchmark" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.optaplanner.org/xsd/benchmark https://www.optaplanner.org/xsd/benchmark/benchmark.xsd">
<benchmarkDirectory>data/acme</benchmarkDirectory>
<inheritedSolverBenchmark>
<solver>
<solutionClass>org.acme.domain.Main</solutionClass>
<entityClass>org.acme.domain.Standstill</entityClass>
<entityClass>org.acme.domain.Visit</entityClass>
<scoreDirectorFactory>
<constraintProviderClass>org.acme.solver.MainConstraintProvider</constraintProviderClass>
<initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
</scoreDirectorFactory>
<termination>
<secondsSpentLimit>30</secondsSpentLimit>
</termination>
</solver>
<problemBenchmarks>
<solutionFileIOClass>org.acme.bootstrap.AcmeSolutionIO</solutionFileIOClass>
<inputSolutionFile>data/latest.xml</inputSolutionFile>
</problemBenchmarks>
</inheritedSolverBenchmark>
<solverBenchmark>
<solver>
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<localSearchType>LATE_ACCEPTANCE</localSearchType>
</localSearch>
</solver>
</solverBenchmark>
</plannerBenchmark>
However, I get this error message:
Exception in thread "main" org.optaplanner.benchmark.api.PlannerBenchmarkException: Benchmarking failed: failureCount (1). The exception of the firstFailureSingleBenchmarkRunner (blankData_Config_0_0) is chained.
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:326)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:100)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkAndShowReportInBrowser(DefaultPlannerBenchmark.java:424)
at org.acme.bootstrap.BenchmarkApp.main(BenchmarkApp.kt:29)
Caused by: java.lang.IllegalStateException: The class (class java.lang.Long) should have a no-arg constructor to create a planning clone.
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.lambda$retrieveCachedConstructor$0(FieldAccessingSolutionCloner.java:90)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
at org.optaplanner.core.impl.domain.common.ConcurrentMemoization.computeIfAbsent(ConcurrentMemoization.java:44)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.retrieveCachedConstructor(FieldAccessingSolutionCloner.java:85)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.constructClone(FieldAccessingSolutionCloner.java:158)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.clone(FieldAccessingSolutionCloner.java:150)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.process(FieldAccessingSolutionCloner.java:207)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.processQueue(FieldAccessingSolutionCloner.java:194)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.cloneSolution(FieldAccessingSolutionCloner.java:136)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.cloneSolution(FieldAccessingSolutionCloner.java:73)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:257)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneWorkingSolution(AbstractScoreDirector.java:250)
at org.optaplanner.core.impl.solver.recaller.BestSolutionRecaller.updateBestSolutionAndFire(BestSolutionRecaller.java:129)
at org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.phaseEnded(DefaultConstructionHeuristicPhase.java:146)
at org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.solve(DefaultConstructionHeuristicPhase.java:98)
at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:99)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:192)
at org.optaplanner.benchmark.impl.SubSingleBenchmarkRunner.call(SubSingleBenchmarkRunner.java:122)
at org.optaplanner.benchmark.impl.SubSingleBenchmarkRunner.call(SubSingleBenchmarkRunner.java:42)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoSuchMethodException: java.lang.Long.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3585)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.lambda$retrieveCachedConstructor$0(FieldAccessingSolutionCloner.java:88)
... 22 more
I've tried many other benchmark configs including with <solverBenchmarkBluePrintType>CONSTRUCTION_HEURISTIC_WITH_AND_WITHOUT_LOCAL_SEARCH</solverBenchmarkBluePrintType> but none of them work either.
I had it working previously, but I went back to it after a number of changes and it no longer works.
I'm using a SimpleLongScore now instead of a SimpleScore and I'm wondering if that has anything to do with the error since before it wasn't throwing this exception.
Any ideas?
Edit #1:
I wish I could provide more code, but I really don't know what code to include.
The bizarre thing is that OptaPlanner runs just fine through mvn compile quarkus:dev, but when I run my benchmark app, from the main entry, it gives the errors as mentioned before, java.lang.IllegalStateException: The class (class java.lang.Long) should have a no-arg constructor to create a planning clone.
Here's my main:
fun main(args: Array<String>) {
val plannerBenchmarkFactory:PlannerBenchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource("benchmarkBluePrintConfig.xml")
val plannerBenchmark: PlannerBenchmark = plannerBenchmarkFactory.buildPlannerBenchmark()
plannerBenchmark.benchmarkAndShowReportInBrowser()
}
The solverConfig.xml can also be the same for both, but only the benchmark app throws the error. It's pretty odd to me.
I figured it out.
In my Visit class I was using a #CustomShadowVariable:
#DeepPlanningClone
#CustomShadowVariable(
variableListenerClass = ArrivalTimeUpdatingVariableListener::class,
sources = [PlanningVariableReference(variableName = "previousStandstill")]
)
var arrivalTime: Long? = null
Removing #DeepPlanningClone solved the problem.
I have no idea why it runs fine when the SolverManager is #Inject'd as opposed to throwing the error when SolverConfig/SolverManager is created through the API (as it is in my Benchmark App).

Spring AOP - Execution coverage

To what classes (in which packages) and methods does this execution apply?
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* com.my.application.service..*Manager.*(..))"/>
</aop:config>
I hade read about Spring AOP on http://spring.io/docs but can't understand the execution expression.
From the spring docs 10.2.3 section in link it is quite clear and execution is used to designate a pointcut.
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
modifiers-pattern - Method visibility (public, protected, private, *)
ret-type-pattern - Return type of the method
declaring-type-pattern - Package or class (ex: com.app.service.* - applies to all classes in this package, com.app.service.UserService - applies only to UserService class, * - all)
name-pattern - method name (ex: set* - all setters)
param-pattern - method parameters (.. - any number of parameters, java.lang.String - method taking String as parameter.
throws-pattern - Method throwing this exception.
In your case
expression="execution(* com.my.application.service..*Manager.*(..))"/>
you are designating this pointcut to all methods whose classname ends with Manager in com.my.application.service package & its sub-packages.

camel with netty4-http - EncoderException

I'm using camel 2.14.0 with netty4-http
and I get the following exception.
the scenario is this:
I have a route that sends a request, waits for the response (inOut) and then sends another request.
the first request works, and then the second one fails.
also, if I do it quickly enough after the failure - the first request will also fail.
while debugging a bit (HttpObjectEncoder) - I saw that in the working flow the state of the request is: state = ST_INIT (0)
and in the request that failed it is: ST_CONTENT_NON_CHUNK (1)
which causes the illegal state when the type of message is HttpMessage
is this a bug or is there anything I can configure to fix it?
Caused by: io.netty.handler.codec.EncoderException: java.lang.IllegalStateException: unexpected message type: DefaultFullHttpRequest
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107)
at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:192)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
at io.netty.channel.AbstractChannelHandlerContext.access$2000(AbstractChannelHandlerContext.java:32)
at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:939)
at io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:991)
at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:924)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:380)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: unexpected message type: DefaultFullHttpRequest
at io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java:63)
at io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:106)
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
... 10 more
I managed to identify the problem:
the first request I sent was a GET request with null body.
in the class org.apache.camel.component.netty4.http.NettyHttpProducer -
the method getRequestBody(Exchange exchange) is creating the actual request object from the exchange.
in it - the method "toNettyRequest" in class org.apache.camel.component.netty4.http.DefaultNettyHttpBinding
checks if the body is null, and if so - it is creating a DefaultHttpRequest, and not DefaultHttpFullRequest
when the request reaches the encoder as a result of a writeAndFlush call - the encoder does not clean its state because of this part of the code:
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
the DefaultHttpRequest is not instanceof LastHttpContent, so the state remains ST_CONTENT_NON_CHUNK and the next request will get an IllegalStateException because the state is not ST_INIT
this bug did not exist in netty-http, it only happened when I moved to use netty4-http
the workaround is simple - use an empty String ("") as body

RESTEasy - Stacktrace in logs when throwing WebApplicationException

I am using Resteasy 2.3.3, bundled with JBoss-AS-7.1.3. I'm trying to
throw a new WebAppliationException, and the output (to the client) seems
fine, but I'm left with an unwanted stack trace in my log. I have a few
other Exceptions mapped, and I was wondering if the mapping was somehow
causing an issue ­ trying to wrap this Exception.
Simple example:
public class SimpleService {
#GET
#Path("stuff")
public String getStuff(final #QueryParam("param1") String param1,
#QueryParam("param2") String param2) throws ActionException {
if (param1==null && param2==null) {
throw new WebApplicationException();
}
I get the following exception:
[WARN] org.jboss.resteasy.core.SynchronousDispatcher#error - failed to execute: javax.ws.rs.WebApplicationException
Any ideas what this error might mean? How I could get rid of the messages?
I stumbled across another class in the javadoc - NoLogWebApplicationException, and it says:
WebApplicationExceptions are logged by RESTEasy. Use this exception
when you don't want your exception logged
https://docs.jboss.org/resteasy/docs/2.3.3.Final/javadocs/org/jboss/resteasy/spi/NoLogWebApplicationException.html

Resources