Can I compose an InvokeDynamic with a FixedValue using Implementation.Composable#andThen()? - byte-buddy

I am building a method "by hand" in ByteBuddy. The method I'm building has one parameter of type ProductType. Let's say it looks like this:
public ProductType frob(ProductType product) {
// stuff that I'm implementing and asking about goes here
}
Inside that method I am building the equivalent of:
product.foo(); // more on this below; foo() has a void return type, which may be important
return product; // FixedValue.argument(0)
This works fine when I build an Implementation like this:
MethodCall.invoke(fooMethodDescription) // invoke foo()...
.onArgument(0) // ...on product...
.andThen(FixedValue.argument(0)); // ...and then return product
(I hope I've typed that right.)
If, however, I build an Implementation like this:
InvokeDynamic.bootstrap(...) // look up foo()'s MethodHandle via my bootstrap method...
.invoke("foo", TypeDescription.VOID) // ...invoke the method handle with a return type of void...
.withArgument(0) // ..."on" the first and only argument (product) and "with" no other arguments...
.andThen(FixedValue.argument(0)); // ...and then return product
…with, of course, the proper InvokeDynamic recipe, the resulting class cannot be verified because of an Operand stack underflow error (Attempt to pop empty stack).
I have a similar InvokeDynamic recipe used many places elsewhere so I know that my problem is not with the InvokeDynamic usage. Rather, it seems to be with the composing? maybe? Is it possible that MethodCall and InvokeDynamic behave differently, even though both are Implementations? Maybe InvokeDynamic doesn't push something on the operand stack (maybe just in the case of void returns?) whereas MethodCall does? Is there something I'm missing in the andThen() usage?
Using ByteBuddy 1.11.2.

As you pointed out correctly, this is a bug in Byte Buddy that is now fixed. Thanks for that. It will be released with version 1.11.3.

Related

How do I use MethodCall.invoke(someElementMatcher) to create a MethodCall representing a method I subsequently define in an instrumented type?

I am using ByteBuddy to generate a class.
Prior to working with DynamicType.Builder, I was going to store a MethodCall as an instance variable:
private final MethodCall frobCall =
MethodCall.invoke(ElementMatchers.named("frob")); // here I invoke a method I'm going to define as part of the instrumented type
Then later in my generation logic for the instrumented type I define the frob method to do something:
.defineMethod("frob")
.intercept(...etc....) // here I define frob to do something
…and I define the (let's say) baz method to invoke frob:
.defineMethod("baz")
.withParameter(...) // etc.
.intercept(frobCall); // invokes "frob", which I've just defined above
(I am trying to keep this simple and may have mistyped something but I hope you can see the gist of what I'm trying to do.)
When I make() my DynamicType, I receive an error that indicates that the dynamic type does not define frob. This is mystifying to me, because of course I have defined it, as you can see above.
Is there some restriction I am unaware of that prohibits ElementMatchers from identifying instrumented type methods that are defined later? Do I really have to use MethodDescription.Latent here?
It should match all methods of the instrumented type. If this is not happening as expected, please set a breakpoint in MethodCall.MethodLocator.ForElementMatcher to see why the method is not showing up. I assume it is filtered by your method matcher.
I noticed however that it did not include private methods which is now fixed and will be released within Byte Buddy 1.10.18.

Reactive Programming - call another Mono on completion #SpringWebFlux

I am trying to achieve the following :
I have two methods -
1. public Mono method1
2. public Mono method2
public Mono<Boolean> test(){
method1.map(status -> {
if(status.isActive){
throw Exception;
}
}).switchIfEmpty(method2).thenReturn(true);
}
Can you help with :
Issue is, control goes to method1, only if method1.subscribe() is used. I am unable to return value or throw exception based on Status field returned from method1.
When method1.map() or method1.filter(), control does not even goto method1
When method1 returns Mono.empty() then control is not going to switchIfEmpty(method2)
Your test method just returns a Publisher. You wont be able to achieve anything with it unless a consumer subscribes to it. This might give you a hint why things might not be working for you as expected.
Also, you haven't even clarified in the question if you're are even calling/subscribing to it or not.

NullReferenceException on bool, int, or other stack variable

First of all: the title of this post does not match the actual question I have.
But I am also supplying the answer to the original problem (NullRefExcp on bool), so other users will find it's solution here by the chosen title.
I have a class, similar to the following:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
Today I had the problem that func crashed with a NullReferenceException at some point although it had been executed successfully many times before.
The exception occured in the line if (!m_bInit)!
I know, you all are saying now, that this is impossible. But it actually was this line. The reason was following:
I have two different variables, both named oTest, but at different places. One of them was initialized: oTest = gcnew CTest. Calling func on this oTest worked well. The first call of func on the other oTest failed with the exception from above. The curious thing is, that the crash seems to happen at the query on m_bInit, also the stacktrace of the exception tells so. But this was just the first place where a member of the not initialized object (it was still nullptr) was called.
Therefore, the advice for other users with the same problem: Check the stack backwards to find a function call on an object that is nullptr/null.
My question now is:
Why does the execution not fail on the first call of a function of oTest which is nullptr?
Why is the function entered and executed until the first access to a member?
Actually, in my case 3 functions were entered and a couple of variables were created on the stack and on the heap...
This code:
void func()
{
if (!m_bInit)
return;
...
}
could actually be written as:
void func()
{
if (!this->m_bInit)
return;
...
}
Hopefully now you can see where the problem comes from.
A member function call is just a regular function call that includes the this parameter implicitly (it's passed along with the other parameters).
The C++/CLI compiler won't perform a nullptr check when calling non-virtual functions - it emits a call MSIL opcode.
This is not actually the case in C#, since the C# compiler will emit the callvirt MSIL opcode even for non-virtual functions. This opcode forces the JIT to perform a null check on the target instance. The only ways you could get this error in C# is by calling the function via reflection or by generating your own IL that uses the call opcode.

Methods with multiple arguments in objective C

If you take this method call for instance(from other post)
- (int)methodName:(int)arg1 withArg2:(int)arg2
{
// Do something crazy!
return someInt;
}
Is withArg2 actually ever used for anything inside this method ?
withArg2 is part of the method name (it is usually written without arguments as methodName:withArg2: if you want to refer to the method in the documentation), so no, it is not used for anything inside the method.
As Tamás points out, withArg2 is part of the method name. If you write a function with the exact same name in C, it will look like this:
int methodNamewithArg2(int arg1, int arg2)
{
// Do something crazy!
return someInt;
}
Coming from other programming languages, the Objective-C syntax at first might appear weird, but after a while you will start to understand how it makes your whole code more expressive. If you see the following C++ function call:
anObject.subString("foobar", 2, 3, true);
and compare it to a similar Objective-C method invocation
[anObject subString:"foobar" startingAtCharacter:2 numberOfCharacters:3 makeResultUpperCase:YES];
it should become clear what I mean. The example may be contrived, but the point is to show that embedding the meaning of the next parameter into the method name allows to write very readable code. Even if you choose horrible variable names or use literals (as in the example above), you will still be able to make sense of the code without having to look up the method documentation.
You would call this method as follows:
int i=[self methodName:arg1 withArg2:arg2];
This is just iOs's way of making the code easier to read.

Code contracts - Assume vs Requires

What's the diference between these two statements ?
Contract.Requires(string.IsNullOrWhiteSpace(userName));
Contract.Assume(string.IsNullOrWhiteSpace(userName));
Imagine you have a method like this:
bool ContainsAnX(string s)
{
return s.Contains("X");
}
Now, this method will always fail if you pass null to it, so you want to ensure this never happens. This is what Contract.Requires is for. It sets a precondition for the method, which must be true in order for the method to run correctly. In this case we would have:
bool ContainsAnX(string s)
{
Contract.Requires(s != null);
return s.Contains("X");
}
(Note: Requires and Ensures must always be at the start of a method, as they are information about the method as a whole. Assume is used in the code itself, as it is information about that point in the code.)
Now, in your code that calls the method "ContainsAnX", you must ensure that the string is not null. Your method might look like this:
void DoSomething()
{
var example = "hello world";
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
This will work fine, and the static checker can prove that example is not null.
However, you might be calling into external libraries, which don't have any information about the values they return (i.e. they don't use Code Contracts). Let's change the example:
void DoSomething()
{
var example = OtherLibrary.FetchString();
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
If the OtherLibrary doesn't use Code Contracts, the static checker will complain that example might be null.
Maybe their documentation for the library says that the method will never return null (or should never!). In this case, we know more than the static checker does, so we can tell it to Assume that the variable will never be null:
void DoSomething()
{
var example = OtherLibrary.FetchString();
Contract.Assume(example != null);
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
Now this will be okay with the static checker. If you have runtime contracts enabled, the Assume will also be checked at run time.
Another case where you might need Assume is when your preconditions are very complex and the static checker is having a hard time proving them. In this case you can give it a bit of a nudge to help it along :)
In terms of runtime behavior there won't be much difference between using Assume and Requires. However, results with the static checker will differ greatly. The meaning of each is different as well, in terms of who is responsible for the error in case of failure:
Requires means that the code which calls this method must ensure the condition holds.
Assume means that this method is making an assumption which should always hold true.
It only differs design-time/static-analysis-time
Contract.Assume:
"Instructs code analysis tools to assume that the specified condition is true, even if it cannot be statically proven to always be true"
And:
At run time, using this method is equivalent to using the Assert(Boolean) method.
Contract.Requires will guarantee that the given predicate is true and static code analyzers might raise an error if they can't 'prove' that is not the case. On Contract.Assume the static analyzer will continue/issue a warning/whatever the tool will decide.
According to official documentation: pages 7 (preconditions) and 11 (assumes).
Requires:
Is a precondition ("preconditions are extressed by using Contract.Requires");
As a precondition will be executed on method invoke;
Assumes:
Not a precondition, not a postcondition, not an invariant;
Is executed at the point where it is specified;
p. 11 "Exist in a build only when the full-contract symbol or DEBUG symbol is defined";