Why does Javassist insist on looking for a default annotation value when one is explicitly specified? - javassist

I am using Javassist to add and modify annotations on a package-info "class".
In some cases, I need to deal with the following edge case. Someone has (incorrectly) specified an #XmlJavaTypeAdapters annotation on the package-info package, but has not supplied a value attribute (which is defined as being required). So it looks like this:
#XmlJavaTypeAdapters // XXX incorrect; value() is required, but javac has no problem
package com.foobar;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
In Javassist, this comes through slightly oddly.
The javassist.bytecode.annotation.Annotation representing the #XmlJavaTypeAdapters annotation does not have a member value (getMemberValue("value") returns null), as expected.
It is of course possible to add a value() member value, and that is what I've done:
if (adaptersAnnotation.getMemberValue("value") == null) {
final ArrayMemberValue amv = new ArrayMemberValue(new AnnotationMemberValue(constantPool), constantPool);
adaptersAnnotation.addMemberValue("value", amv);
annotationsAttribute.addAnnotation(adaptersAnnotation);
}
In the code snippet above, I've created a new member value to hold an array of annotations, because the value() attribute of #XmlJavaTypeAdapters is an array of #XmlJavaTypeAdapter. I've specified its array type by trying to divine the Zen-like documentation's intent—it seems that if you supply another MemberValue that this MemberValue will somehow serve as the array's type. In my case I want the type of the array to be #XmlJavaTypeAdapter, which is an annotation, so the only kind of MemberValue that seemed appropriate was AnnotationMemberValue. So I've created an empty one of those and set it as the array type.
This works fine as far as it goes, as long as you stay "within" Javassist.
However, something seems to have gone wrong. If I ask Javassist to convert all of its proprietary annotations into genuine Java java.lang.annotation.Annotations, then when I try to access the value() attribute of this #XmlJavaTypeAdapters annotation, Javassist tells me that there is no default value. Huh?
In other words, that's fine—indeed there is not—but I have specified what I had hoped was a zero-length array (that is, the default value shouldn't be used; my explicitly specified zero-length array should be used instead):
final List<Object> annotations = java.util.Arrays.asList(packageInfoClass.getAnnotations());
for (final Object a : annotations) {
System.out.println("*** class annotation: " + a); // OK; one of these is #XmlJavaTypeAdapters
System.out.println(" ...of type: " + a.getClass()); // OK; resolves to XmlJavaTypeAdapters
System.out.println(" ...assignable to java.lang.annotation.Annotation? " + java.lang.annotation.Annotation.class.isInstance(a)); // OK; returns true
if (a instanceof XmlJavaTypeAdapters) {
final XmlJavaTypeAdapters x = (XmlJavaTypeAdapters)a;
System.out.println(" ...value: " + java.util.Arrays.asList(x.value())); // XXX x.value() throws an exception
}
}
So why is Javassist looking for a default value in this case?
My larger issue is of course to handle this (unfortunately somewhat common) case where #XmlJavaTypeAdapters is specified with no further information on it. I need to add a value member value that can hold an array of #XmlJavaTypeAdapter annotations. I can't seem to figure out how to accomplish this with Javassist. As always, all help appreciated.

For posterity, it appears that in this particular case (to avoid a NullPointerException and/or a RuntimeException), you need to do this:
if (adaptersAnnotation.getMemberValue("value") == null) {
final ArrayMemberValue amv = new ArrayMemberValue(constantPool);
amv.setValue(new AnnotationMemberValue[0]);
adaptersAnnotation.addMemberValue("value", amv);
annotationsAttribute.addAnnotation(adaptersAnnotation);
}
Note in particular that I deliberately omit the array type when building the ArrayMemberValue (including one of any kind will result in an exception). Then I explicitly set its value to an empty array of type AnnotationMemberValue. Any other combination here will result in an exception.
Additionally, and very oddly, the last line in that if block is critical. Even though in this particular case the annotation itself was found, and so hence was already present in the AnnotationsAttribute, you must re-add it. If you do not, you will get a RuntimeException complaining about the lack of a default value.
I hope this helps other Javassist hackers.

Related

Function that can return something or nothing

Is it possible to define a function in Kotlin where you can either return something or return nothing? I thought maybe to use Any as the return type, but that still requires the function to return something, although perhaps there is a way to return a Unit when the return type is Any?
I also found "Nothing":
Nothing has no instances. You can use Nothing to represent "a value that never exists": for example, if a function has the return type of Nothing, it means that it never returns (always throws an exception).
Unfortunately that will throw an exception. That's too bad. I wonder why they throw an exception?
You can wrap the result in a sealed class
sealed class Result<out T> {
data class Success<out T>(val value: T): Result<T>()
object Failure: Result<Nothing>()
}
Then for calling it you can
fun <Type>calculateResult(...): Result<Type> {
//calculate and return some implementation
}
And then
val result = calculateResult(inputs)
when (result) {
is Success -> {
val value = success.value
}
is Failure -> {
//Do something like show an error the user you know your value is Nothing
}
}
You can just use a nullable return type.
Otherwise, to address whether you can return Unit, you can. Unit is just a Kotlin object so you can get the instance by name:
return Unit
However I wouldn't recommend it, there are plenty of better options.
In regards to Nothing, it is a special type that is used to represent a function never returning. So if I wanted to write a function that throws an exception, I could do so with the Nothing return type. Then the inference engine knows that nothing past my function call will get executed.
Well if you think about it, a function can't return something or nothing, because what's the result of calling it? Do you have a value, or nothing at all? If you assign the result to a variable, but there is no result, that variable has no value, so what is it? The function has to either be defined as always returning something or always returning nothing, so you always know if there's a return value and what its possible types are. Otherwise we're getting into philosophical territory!
In fact in Kotlin, functions always return something - if you don't specify a type, like a void function in Java, it will default to returning Unit. This is a special value that represents a function not returning a result, but it is still a result type that gets returned. It's not nothing, it's a a thing. Every function has to return a thing.
So if you want to define the thing you return as either "a value that represents a thing" or "a value that represents nothing", you need a type that is capable of expressing both those ideas. You have three basic approaches I think:
use a specific value to represent "no value", e.g. -1 for an Int, "NO_VALUE" for a String, that kind of thing
create a type that defines a "no value" version of itself, like the Result type in one of the answers, the Optional type in Java, etc
just use null because nullable versions of every type are built into Kotlin's type system, and the standard library is geared towards handling them. Check out these features built around working with nulls
Use the nullable types IMO - return a String? or whatever and if the result is non-null, do something with the value. If it is null, ignore it. Kotlin makes that pretty easy! If you get to the point where you need to roll a special type, you'll probably know why you need it over your good friend null

Scala doobie fragment with generic type parameter

I am trying to abstract inserting objects of different types into sql tables of similar structure. Here's what I'm trying to do:
class TableAccess[A : Meta](table: String) {
def insert(key: String, a: A): ConnectionIO[Unit] = {
(fr"insert into " ++ Fragment.const(table) ++ fr" values ($key, $a);").update.run.map(_ => ())
}
}
But I get this compile error:
[error] diverging implicit expansion for type doobie.util.param.Param[A]
[error] starting with method fromMeta in object Param
[error] (fr"insert into " ++ Fragment.const(table) ++ fr" values ($key, $a);").update.run.map(_ => ())
All I can find in the documentation is:
doobie allows you to interpolate values of any type (and options
thereof) with an Meta instance, which includes...
But it seems that is not enough in this case; what's the right typeclass/imports/conversions I need?
I'll go ahead an answer my own question, almost a year later. I never fully understood what was happening, and I have since updated to a newer version of doobie, so I am not sure how relevant this is. But now the documentation contains this clue:
Note: it is important to understand that Meta exists only to introduce
Get/Put pairs into implicit scope. You should never demand Meta as
evidence in user code: instead demand Get, Put, or both.
def foo[A: Meta](...) // don't do this
def foo[A: Get: Put](...) // ok
And indeed, between that change and the new version, this now compiles just fine for me:
class TableAccess[A: Get: Put](table: String) {
When the compiler is resolving implicit its searches for one of a specific type in the current scope. Here it seems like his finding more than one in his tree search.
It's not a matter of a missing typeclass or imports, it's more like you have too many of them and the compiler cant figure the right one.
Try removing some implicit and see how that works or pass them explicitly.
One way I resolved this was to localize the type parameters (and their evidence) onto the method (on a static/companion object), and then it compiled.
Something like
object MinimalGood {
def good[A: Meta, B: Meta](a: A, b: B): Update0 =
sql"""$a $b""".update
}

Check field errors in word references with VSTO

How can I check if some fields in my word have errors? I have a large document that contains many references to other chapters or images. When those chapters or images are missing in the document, the fields containing those references will display Error! Reference Source Not Found instead of the reference.
The problem is, that I need to create an algorithm that will check for those reference errors, no matter what the locale and language of the file is. The problem is, that this field error is localized in the language of the system of the user who uses the word.
How can I do this? Is there any property on Field that can be used to check if the source is available?
Currently, I check for errors in the fields by using the result text of the field:
Int32 fieldErrors = 0;
foreach (Word.Field field in doc.Fields)
{
field.Update();
if (field.Result.Text.StartsWith("Error!"))
++fieldErrors;
}
Unfortunately, this will only work in english word instances.
In the documentation for Field types it is seen that a Field instance has an Update() method that returns a bool. The documentation does not state what the semantic meaning of the return value is, however, by doing a short empirical study I found that the method returns true if the Update() succeeded and false if the update did not succeed. This means that in order to find fields with errors you can do something like:
var fieldsWithErrors = new List<Field>();
foreach (Field field in document.Fields)
{
if(!field.Update())
fieldsWithErrors.Add(field);
}
... or shorter with LINQ:
var fieldsWithErrors = document.Fields.Cast<Field>().Where(field => !field.Update()).ToList();
Another (and faster) approach would be to use the Update() method exposed by the Fields collection.
var indexOfFirstError = document.Fields.Update();
... the method returns the index of the first field with an error. If no errors are found, the method returns 0.
For complete documentation please see the MSDN references:
Field.Update()
Fields.Update()
Field members
Fields members

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";

Why does resolveBinding() return null even though I setResolveBindings(true) on my ASTParser?

I am writing an Eclipse plug-in that uses JDT AST's ASTParser to parse a method. I am looking within that method for the creation of a particular type of object.
When I find a ClassInstanceCreation, I call getType() on it to see what type is being instantiated. I want to be sure that the fully-resolved type being dealt with there is the one I think it is, so I tell the resultant Type object to resolveBinding(). I get null back even though there are no compilation errors and even though I called setResolveBindings(true) on my ASTParser. I gave my ASTParser (via setSource()) the ICompilationUnit that contains my method, so the parser has access to the entire workspace context.
final IMethod method = ...;
final ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setSource(method.getCompilationUnit());
parser.setSourceRange(method.getSourceRange().getOffset(), method.getSourceRange().getLength());
parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);
final TypeDeclaration astRoot = (TypeDeclaration) parser.createAST(null);
final ClassInstanceCreation classInstanceCreation = walkAstAndFindMyExpression(astRoot);
final Type instantiatedType = classInstanceCreation.getType();
System.out.println("BINDING: " + instantiatedType.resolveBinding());
Why does resolveBinding() return null? How can I get the binding information?
Tucked away at the bottom of the overview of ASTParser.setKind(), carefully hidden from people troubleshooting resolveBinding() and setResolveBindings(), is the statement
Binding information is only computed when kind is K_COMPILATION_UNIT.
(from the online Javadoc)
I don't understand offhand why this would be the case, but it does seem to point pretty clearly at what needs to be different!