How to enable ALLOW_NON_NUMERIC_NUMBERS with Jackson ObjectMapper 2.12? - jackson-databind

This line of code gives a deprecation warning:
mapper.configure(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS, true);
And this doesn't compile
mapper.configure(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS, true);
because JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS not a subclass of any of the four Feature types ObjectMapper supports.
What is the correct was to enable this feature with Jackson 2.12?

There doesn't seem to be any API that accepts JacksonFeature or JsonReadFeature as parameter.
DeserializationConfig accepts FormatFeature as parameter but you can't change this property of ObjectMapper after getting a new instance by calling withFeatures().
The only solutions seems to be to get the feature out of the JsonReadFeature which is then no longer deprecated:
mapper.enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS.mappedFeature());
(note the method call at the end of the enum).

Related

Nullability mismatch in simple assignment after switching to sound null safety

I switched to sound null safety and started getting runtime error in a simple assignment, that should never happen with sound null safety:
final widgetOnPressed = widget.onPressed;
Error:
type '(LogData) => void' is not a subtype of type '((LogData?) => void)?'
I can repro it for Flutter versions 2.12.0-4.1.pre and 2.13.0-0.0.pre.505.
PR: https://github.com/flutter/devtools/pull/3971
Failing line: https://github.com/flutter/devtools/blob/9fc560ff2e6749459e2ca6a1dc00bf6fb16ed93b/packages/devtools_app/lib/src/shared/table.dart#L1184
To repro, start DevTools at this PR for macos, connect to an app and click the tab 'Logging'. DevTools will show red screen and error in console.
Is it dart bug or the app bug? If it is the app bug, how can I debug it?
It's a bug in your code.
You didn't say which kind of error you got - a compile-time error or a runtime error. I'm guessing runtime error. (Well, you did say to launch it in the debugger, so that is a good hint too.)
The line final widgetOnPressed = widget.onPressed; looks like it can't possibly fail. After all, the type of the local variable is inferred from the expression assigned to it, and the runtime value of that expression will surely be a subtype of the static type because the type system is sound!
Isn't it? ISN'T IT?
It's not, sorry. Dart 2's type system is mostly sound, even more so with null safety, but class generics is covariant, which can still be unsound. It's fairly hard to hit one of the cases where that unsoundness shows its ugly head, but returning a function where the argument type is the class's type variable is one.
Your state class extends State<TableRow<T?>>, so the widget getter returns a TableRow<T?>. The onPressed of that type has type ItemCallback<T?>?, aka, void Function(T?)?.
You create a _TableRowState<LogData>, with its widget which has static type TableRow<LogData?>, but you somehow manage to pass it a TableRow<LogData> instead. That's fine. Class generics are covariant, so all is apparently fine at compile-time.
Then you do final widgetOnPressed = widget.onPressed;.
The static type of widgetOnPressed is void Function(LogData?) here.
The actual runtime type of onPressed is void Function(LogData) because it's from a TableRow<LogData>.
A void Function(LogData) is-not-a void Function(LogData?) because the former cannot be used in all places where the latter can (in particular, it can't be used in a place where it's called with null).
This assignment is potentially unsound, and actually unsound in this case. The compiler knows this and inserts an extra check to ensure that you don't assign a value to the variable which isn't actually valid. That check triggers and throws the error you see.
How do you avoid that?
Don't create a TableRow<LogData> where a TableRow<LogData?> is required.
Or type the variable as:
final ItemCallback<T>? widgetOnPressed = widget.onPressed;
(no ? on the T).
Or rewrite everything to avoid returning a function with a covariant type parameter (from the class) occurring contra-variantly (as an argument type).
Which solution fits you depends on what you want to be able to do.

dart nullsaftey and using old packages

I've enabled the dart 2.8 nullsaftey experiment.
I've converted my app to nullsaftey but its using an old pre-nullsafety package.
The problem is that the old package has a method which can return null:
/// Returns the environment variable with [name] or null if it doesn't
/// exist
String env(String name);
Which is used as follows:
var home = env('HOME');
If the HOME environment variable is missing, env returns null.
The problem is that env is declared as returning a String.
So when I write
var home = env('HOME');
home ??= '/home';
I get an error:
The operand can't be null, so the condition is always false.
Try removing the condition, an enclosing condition, or the whole conditional statement.
Given that all the nullsaftey release announcements say you can use nullsaftey with older packages, I'm guessing there is some way to declare an imported packages as non-nullsafe.
Problem is that I can't find any documentation on how to do this.
null safety has not been released yet! that is why you need to provide the experiment flag.
Language versioning
By default, whether or not null safety is supported in a library is determined by its language version. Any language version 2.8 or lower counts as opted out of null safety, and 2.9 or higher (subject to change) is opted in. The language version itself can come from one of two places:
The minimum bound of the package's declared SDK constraint. The following package will have a language version of 2.8.
name: foo
env:
sdk:
">=2.8.0 <3.0.0"
A language override comment at the top level of the file, before any other declarations. The following library will have a language version of 2.8.
// #dart=2.8
class Foo {}
The language override comment will take precedence over the SDK constraint, but only within the single library where it is declared.
Interaction between null safe and non-null safe code
The problem you are having is reproducible without different packages or incorrect language versions though, and has to do with the interaction between null-safe and non-null-safe code. Consider the following example:
// #dart=2.8
String foo() {
return null;
}
// #dart=2.9
import 'a.dart';
void main() {
var value = foo();
value ??= 'asd';
}
The return type of foo doesn't become String?, instead it gets tagged as String* - this is known as a legacy type. A legacy type is treated as a non-null type in opted in libraries. The goal of legacy types is to make it easier to migrate to null-safety through an in-order migration
Consider the example below:
// #dart=2.9
void foo(String value) {
// do something with non-null String.
}
// #dart=2.8
import 'a.dart';
void main() {
foo(getStringFromAPI());
}
While foo requires a non-null string, it isn't possible for the entry-point to actually pass it one - since it has not opted in yet. Without the treatment of legacy types as non-nullable types, it would not be possible to gradually migrate - because all libraries would need to be updated at once, or only updated to accept nullable types.
Out of order migration
By calling code that has not been migrated to null-safety from a null safe library, you are increasing the risk that you will be broken when that dependency eventually migrates. In you example, if home was treated as non-nullable then updating to a version of the dependency with an updated return value of String? would cause a compilation error.
For your specific case, I would recommend specifically annotating the type of home as String?. This is a perfectly valid type annotation, since in general T and T* are always assignable to T?. It also more correct, since you know the API can return null.
String? home = env('HOME');
home ??= '/home';
EDIT June 2021:
Null safety has released, yay! The first version of Dart with null safety enabled by default ended up being 2.12 and not 2.9 as documented in the question above.

Default constructors in Xamarin.Android

I am new to Android development with Xamarin.Android and I would like to understand how to have the next issue fixed.
Sometimes after restoring my Android application from background I was facing the next error:
Unable to find the default constructor on type MainMenuFragment. The MainMenuFragment is used by the application NavigationDrawerActivity to allow users to switch between different Fragments inside the app.
In order to solve it, I added a default constructor to the MainMenuFragment as described inside the next links:
Xamarin Limitations - 2.1. Missing constructors
Added a default constructor, should fix the issue.
public class MainMenuFragment : DialogFragment
{
readonly NavigationDrawerActivity navigationDrawer;
#region Constructors
public MainMenuFragment () {} // Default constructor...
public MainMenuFragment (NavigationDrawerActivity navigationDrawer, IMenuType launchMenu = null)
{
if (navigationDrawer == null)
throw new ArgumentNullException ("navigationDrawer");
this.navigationDrawer = navigationDrawer;
...
Fragment UpdateTopFragmentForCurrentMenu (Fragment newMenuRootFragment = null)
{
Fragment currentMenuRootFragment = navigationDrawer.CurrentFragment; // issued line.
But now sometime in the future, the MainMenuFragment gets initialized using its default constructor and at the first time it tries to access its navigationDrawer it throws a System.NullReferenceException:
System.NullReferenceException: Object reference not set to an instance of an object
at MainMenuFragment.UpdateTopFragmentForCurrentMenu (Android.App.Fragment) <0x00018>
at MainMenuFragment.OpenMenu (IMenuType,bool) <0x0006b>
at MainMenuFragment.OnCreate (Android.OS.Bundle) <0x00053>
at Android.App.Fragment.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x0005b>
at (wrapper dynamic-method) object.3919a6ec-60c1-49fd-b101-86191363dc45 (intptr,intptr,intptr) <0x00043>
How can I have a default constructor implemented without facing this null reference exception?
You're programming like a C# developer, thats what the problem is :) I faced these same hurdles learning monodroid.
Take a look at the examples out there, in java, you'll see almost all the time they initialize using a static method like object.NewInstance() which returns object. This is how they initialize their views/receivers/fragments. At that point they populate the Arguments property and store that in the fragment. You need to remove all your constructors EXCEPT the empty ones and use arguments to pass your data around. If you try to do this using constructors and regular oo concepts you'll be in for a world of hurt. Arguments.putExtra and all those methods are there. It makes things a little verbose but once you get the hang of it you'll start creating some helper methods etc.
Once you get that sorted, you'll need to figure out if you need to recreate your fragments everytime the activity is resumed and if not, mark them as RetainInstance = true as well as get them onto a fragmentmanager which will help you retain all your state.
If you haven't built on android before it's weird and certainly not what I expected. But it's reeaaallly cool, much more awesome than I expected too. And same with Xamarin.
Great similar question: Best practice for instantiating a new Android Fragment

How to define a method for the class 'Proxy' in Dart js-interop?

I'm currently calling a jQuery based plugin called Bootstrap Context Menu.
In order to call it, I need to use the Javascript Interop library. But when I call a jQuery method from it I receive the following warning:
The method 'jQuery' is not defined for the class 'Proxy'
Code snippet:
js.scoped(() {
js.context.jQuery('#canvas').contextmenu();
});
This was not happening before some dart/js-interop updates. What is the right way to get rid of this warning?
You get this warning because the new analyzer doesn't seem to be aware of the option Report 'no such member' warnings when class defines noSuchMethod() ( Reported at http://dartbug.com/10016 ). If you switch back to the legacy analyzer you shouldn't see this warning anymore.
That said if you want to use the new analyzer and get rid of this warning you can use the array notation like this :
js.context["jQuery"]('#canvas')["contextmenu"]();
But :
it's less readable particullary for method calls.
it's less efficient for method calls because 2 operations are done ( f = js.context["jQuery"] followed by f('#canvas') ) instead of 1 ( js.context.jQuery('#canvas') )

Specifying optional parameters when calling JavaScript functions in Dart

I'm calling the function window.navigator.geolocation.getCurrentPosition from Dart code. The final parameter to this function is optional. In JavaScript I would set the optional parameters as follows:
var wpid = navigator.geolocation.watchPosition(geo_success, geo_error,
{enableHighAccuracy:true, maximumAge:30000, timeout:27000});
What would the equivalent be in Dart code? I've tried the following but I'm not sure if it is correct:
window.navigator.geolocation.watchPosition(geo_success, geo_error,
{'enableHighAccuracy':true, 'maximumAge':30000, 'timeout':27000});
You are using this method: http://api.dartlang.org/docs/bleeding_edge/dart_html/Geolocation.html#watchPosition
int watchPosition(PositionCallback successCallback, [PositionErrorCallback errorCallback, Object options])
I do not have Dark SDK on this machine, but to me it looks completely fine. If the JavaScript equivalent code is just an object, then passing a Dart Map just like what you have done should be working. Is there a problem with it?
Hopefully passing a Map works, please try and let us know.
Even if it does work, this is a bad Dart API. The options really should be optional parameters, not properties of an options object. I filed a bug here: http://dartbug.com/6280

Resources