JMeter setTestLogicalAction from JMeterContext gives "Cannot reach instance method" - java

JMeter 5.1. The following link gives a working code Restarting a user thread conditionally in JMeter where setTestLogicalAction is called from SampleResult. the method is indeed listed in methods in https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html.
However, it's also listed in https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterContext.html but using org.apache.jmeter.threads.JMeterContext.setTestLogicalAction gives
ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: `` import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter . . . '' : Cannot reach instance method: setTestLogicalAction( org.apache.jmeter.threads.JMeterContext$TestLogicalAction ) from static context: org.apache.jmeter.threads.JMeterContext
Why can't I use setTestLogicalAction from JMeterContext? What do I miss about classes in java?
Also, the code from above mentioned post works in beanshell, but neither that nor modified as above code works in JSR223+Groovy. After taking notice that methods are not static, code is as below (both paths were tried, finally I list them together) in groovy, no errors, but thread continues, not restarted...
jmco = new org.apache.jmeter.threads.JMeterContext();
jmsr = new org.apache.jmeter.samplers.SampleResult();
jmco.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
jmsr.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
Can I use setTestLogicalAction in groovy script?
P.S. interesting how beanshell can call non-static method w/o instantiation ...
ADDED 2019/04/01:
def mycontext = org.apache.jmeter.threads.JMeterContextService.getContext()
mycontext.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
the code was changed to the above after suggestion in Dmitri answer, but the code does not restart the thread.

If you're not that good at programming go for Flow Control Action sampler instead of trying to replicate its functionality in code, in any case it will be faster.
There is no need to instantiate neither JMeterContext nor SampleResult as they're pre-defined in JSR223 Test Elements, moreover you're doing this wrong, i.e. correct way of accessing JMeterContext is calling JMeterContextService.getContext() function
Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting so I would recommend forgetting about Beanshell.

prev.setTestLogicalAction(org.apache.jmeter.threads.JMeterContext.TestLogicalAction.START_NEXT_ITERATION_OF_CURRENT_LOOP)
worked for me (from a Groovy based post processor).

Related

Collect custom Doc annotations in Java/Kotlin project?

I'm going to use lots of custom documentation notes all around code base of Kotlin and Java project. Seems like reasonable choice would be to use annotation.
As far as I know annotation is some sort of magic, handled by build tools. But I need to work with it in the Kotlin/Java code.
So we have two files /src/some/thing.kt
package some
annotation class Doc
#Doc
private fun some_doc() {
println("some doc")
}
and /src/generate_docs.kt
fun main() {
Find and call all the functions over all
the codebase marked with #Doc
And then run some other code to process
those notes and output HTML docs
}
How could it be done? Basically I can do it by manually writing all those calls, but I hope there's a better way.
fun main() {
some_doc()
another_doc()
yet_another_doc()
...
couple tens or hundreds more lines
And then run some other code to process
those notes and output HTML docs
}
If possible I would like to avoid Maven plugins and magic and just have plain old Java/Kotlin code I can run as java GenerateDocsKt.

How Can I Verify varargs To RPC Calls Before Runtime?

I can make an RPC call in Java like this:
final FlowHandle flowHandle = rpcOps.startFlowDynamic(
TransferObligation.Initiator.class,
linearId, newLender, true);
The first parameter is the class to invoke and the next three are arguments to the class passed via varargs.
As we can see by the class definition the args match and the call works fine:
public Initiator(UniqueIdentifier linearId, Party newLender, Boolean anonymous) {
this.linearId = linearId;
this.newLender = newLender;
this.anonymous = anonymous;
}
However, if I add or remove args from the constructor the code will still compile and I will only notice at runtime (or integration testing - assuming I have enough test coverage).
The same applies if I pass the wrong args in the first place in the RPC call.
e.g. the following compiles fine but gives a runtime error:
final FlowHandle flowHandle = rpcOps.startFlowDynamic(
TransferObligation.Initiator.class,
linearId, newLender, true, 100000L, "Random String");
Is it possible to check for these errors with something other than test cases?
e.g. Static analysis using a custom IDEA code inspection or a custom SonarQube rule
EDIT: It appears that the Kotlin API has a type safe way of starting the flows (using inline reified extension functions) that the Java API does not, so I have removed the kotlin tag and updated the references to Java examples.
Along with CordaRPCOps.startFlowDynamic which as you mentioned has a varargs parameter for the Flow constructor arguments, there is CordaRPCOps.startFlow methods, which is basically nothing more than extension function for type-safe invocation of flows.
CordaRPSOps.kt

Eclipse Groovy DSLDs and static compilation

Is it possible to define Eclipse Groovy DSLD (DSL Definition) which can be statically compilable?
I tried to use DSLD example provided by Eclipse, so I created TestDsl.dsld:
contribute(currentType(subType('groovy.lang.GroovyObject'))) {
property (
name : 'newProp',
type : String,
provider : 'Sample DSL',
doc : 'This is a sample. You should see this in content assist for GroovyObjects: <pre>newProp</pre>')
}
Then I wrote a test class using previous property. This class should be compiled statically. Eclipse is showing new property as a valid one, but then it fails to compile.
Same result occurs using both #CompileStatic and #TypeChecked.
DSLDs introduce new methods and properties into content assist and type inferencing. This does not guarantee the methods or properties will be available at compile- or run-time. They operate more like hints than anything.
Quite often, DSLDs are used to fill a gap that exists between the static type checker and the dynamic execution state of your program. If you want something that is compatible with #TypeChecked or #CompileStatic, you may need to write a TypeChekingExtension instead of a DSLD contribution.

AWS Lambda Trigger in code; Java

So in a lot of AWS Lambda tutorials, it teaches us to write a few lines of code, package it, and upload it.
Is there a code example where you can just trigger/call the lambda in your current project using the ARN or something? My current project is huge and I can't/it's not preferable to upload the function package to AWS Lambda, I just want to trigger it in my current code.
One link I found is: https://aws.amazon.com/blogs/developer/invoking-aws-lambda-functions-from-java/ but it does not work for me so far.
Apologies if it's been asked already; I didn't find anything useful to me.
EDIT:
My problem is the lambda function only gets invoked because I've uploaded it as a JAR (ie. its not a part of my main project, I just did it as a test), but I want to write the code to be invoked in my main project. I don't know how to invoke the lambda in my Java code. Like #MaxPower said, perhaps I have this all wrong and this is not possible.
What I do is create an interface with the #LambdaFunction annotation.
public interface Foo {
#LambdaFunction(functionName = "LambdaName")
OutputObject doFoo(InputObject inputObject);
}
Then in the class that is to call the lambda I make a Lambda client
private final Foo fooCaller;
RunTest() {
ProfileCredentialsProvider lambdaCredentialsProvider = new ProfileCredentialsProvider("lambda");
AWSLambdaClientBuilder builder = AWSLambdaClientBuilder.standard().withCredentials(lambdaCredentialsProvider);
builder.setRegion("us-east-1");
AWSLambda awsLambda = builder.build();
LambdaInvokerFactory.Builder lambdaBuilder = LambdaInvokerFactory.builder();
lambdaBuilder.lambdaClient(awsLambda);
fooCaller = lambdaBuilder.build(Foo.class);
}
then when you want to call the lambda
fooCaller.doFoo();

POI for XPages - using xwpfdocument

To help solve another problem I have, I'm testing the following code in the postGenerationProcess event of the POI Word widget:
var jce:writeXWPFDocument = new writeXWPFDocument();
var newString3 = jce.doSomething3(xwpfdocument);
print("newString3 = " + newString3);
doSomething3 is defined in a Java class contained in the .nsf.
public class writeXWPFDocument {
public String doSomething3(XWPFDocument xwpfdocument) {
return "DO SOMETHING - xwpfdocument";
}}
When I run this code, I get the error:
Java method 'doSomething3(org.apache.poi.xwpf.usermodel.XWPFDocument)'
on java class 'AZGPackage.writeXWPFDocument' not found
What could be causing this error?
#Knut Hermann - this is a test which relates to the other problem you have been helping me with.
Edit to make the correct answer easier to find:
I have used poi in a few applications. I've encountered similar problems twice: First, usually when I accidentally import a class with the same name from the wrong package (like lotus.local.domino.Database instead of lotus.domino.Database). The other time I encountered this (and the only time the package name was identical) was when I had poi in a plug-in that I had added to the build path and also had it installed by a poi extension library I had built. If you can't cast an object as itself, there is an issue with the ClassLoader, and I don't know what would cause that other than a class being listed twice.
SSJS seems to pass a different object type to the function. Try to change the class of the parameter to Object and for testing return the class name.
In a production code you could check with instanceof if the parameter has the right data type.
In General: consider using a facade pattern, so you keep your complex Java classes away from SSJS

Categories

Resources