String to Object conversion - not working in Java 11 - java-11

Below code snippet works fine in Java 1.8, but not working with Java 11 SDK.
public static void main(String[] args) {
String jsonText = "{\"user\":{\"name\":\"mrhaki\",\"age\":38,\"interests\":[\"Groovy\",\"Grails\"]}}";
JsonSlurper jsonSlurper = new JsonSlurper();
Object result = jsonSlurper.parseText(jsonText);
Map jsonResult = (Map) result;
Map user = (Map) jsonResult.get("user");
String name = (String) user.get("name");
Integer age = (Integer) user.get("age");
List interests = (List) user.get("interests");
assert name.equals("mrhaki");
assert age == 38;
assert interests.size() == 2;
assert interests.get(0).equals("Groovy");
assert interests.get(1).equals("Grails");
}
While trying to run the above code snippet in Java 11, getting the below exception.
Exception in thread "main" java.lang.ClassCastException: class [B cannot be cast to class [C ([B and [C are in module java.base of loader 'bootstrap')
at groovy.json.internal.FastStringUtils$StringImplementation$1.toCharArray(FastStringUtils.java:88)
at groovy.json.internal.FastStringUtils.toCharArray(FastStringUtils.java:175)
at groovy.json.internal.BaseJsonParser.parse(BaseJsonParser.java:103)
at groovy.json.JsonSlurper.parseText(JsonSlurper.java:208)
at groovy.json.JsonSlurper$parseText.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at Test.main(Test.groovy:9)
Please explain the cause and reason behind this ?
Also, what is the alternative way to convert String to Object in Java 11 ?
Thanks in advance!

The message “class [B cannot be cast to class [C” indicates that the method is trying to cast a byte[] array to a char[] array. Since the code location also has a name like FastStringUtils.toCharArray, I can guess what happens here.
This class seems to hack into the java.lang.String class and read its value field in a questionable attempt of performance improvement. Since Java 9, this internal array is a byte[] array instead of a char[] array, which makes this hack fail at runtime.
You need an updated version of the library or a configuration option disabling that hack, if it exists.

Related

c# ReadOnlyMemory from pointer

Hi there I have a c native library that is returning me json as char*. What I would like to do in c# is to use this pointer and write it straight to the
this.ControllerContext.HttpContext.Response.BodyWriter;
I'm able to create ReadOnlySpan from the ptr but as far as I can tell PipeWriter only accepts ReadOnlyMemory<byte> which does not have a constructor from IntPtr. Is there a way to create ReadOnlyMemory<byte> from IntPtr or some other way to writer my string from native library withou copying it one extra time?
This answer provides a solution that does not need to copy the entire buffer:
Marshalling pointer to array P/Invoke
TL;DR: Take UnmanagedMemoryManager from Pipelines.Sockets.Unofficial by Marc Gravell.
int* ptr = ...
int len = ...
var memory = new UnmanagedMemoryManager<int>(ptr, len).Memory;
Unfortunately, you still need to allocate the MemoryManager (it must be a class, not a struct).
Thank you for your answers but none of them was without extra copy. I was finally figure it out so in case somebody struggle with it, here is the solution.
So the only way I as able to achieve this is like.
await Response.StartAsync(HttpContext.RequestAborted);
var dest = Response.BodyWriter.GetMemory((int)jsonLen).Pin();
unsafe { memcpy(dest.Pointer), srcPtr, srcLen); }
Response.BodyWriter.Advance(srcLen);
await Response.BodyWriter.FlushAsync(HttpContext.RequestAborted);
Maybe use something like this?
public class Utility
{
public System.ReadOnlyMemory<T> ConvertToReadOnlyMemory(System.ReadOnlySpan<T> input) {
var tmp = new System.Memory<T>();
input.CopyTo(tmp.Span);
return (System.ReadOnlyMemory<T>)tmp;
}
}
However, I think this will involve completely copying the stream into heap storage, which is probably not what you want...
I glad if this could speed up and match to what you wants.
namespace Helper
{
using System;
using System.Runtime.InteropServices;
public static class CStringMapper
{
// convert unmanaged c string to managed c# string
public string toCSharpString(char* unmanaged_c_string)
{
return Marshal.PtrToStringAnsi((IntPtr)unmanaged_c_string);
}
// Free unmanaged c pointer
public void free(char* unmanaged_c_string)
{
Marshal.FreeHGlobal((IntPtr)unmanaged_c_string);
}
}
}
Usage:
using Helper;
/* generate your unmanaged c string here */
try
{
// eg. char* OO7c = cLibFunc();
string cSharpString = CStringMapper.toCSharpString(OO7c);
}
finally
{
// Make sure to freeing the pointer
CStringMapper.free(OO7c);
}

What is this Objective C code doing

I am a developer in C-like languages (Java/JavaScript/C#) and I am attempting to convert some Objective-C code into Java.
For the most part, it is relatively straightforward but I have hit a stumbling block with the following bit of code:
typedef struct {
char *PAGE_AREA_ONE;
char *PAGE_AREA_TWO;
char *PAGE_AREA_THREE;
} CODES;
- (CODES*) getOpCode {
CODES *result = NULL;
result = malloc(sizeof(CODES));
result->PAGE_AREA_ONE = "\x1b\x1b\x1b";
result->PAGE_AREA_TWO = "\x2d\x2d\x2d";
result->PAGE_AREA_THREE = "\x40\x40";
return result;
}
What would the Java equivalent of this be? From what I can tell in other areas of the code, it is being used to store constants. But I am not 100% certain.
Thanks.
The typedef is just creating a structure that contains three string properties. The getOpCode method is apparently trying to create a new structure and assign values to those three properties. C# code would be:
public class Codes
{
public string PageAreaOne;
public string PageAreaTwo;
public string PageAreaThree;
}
public Codes GetCodes()
{
Codes result = new Codes();
result.PageAreaOne = "\x1b\x1b\x1b"; // three ESC characters
result.PageAreaTwo = "---";
result.PageAreaThree = "##";
return result;
}
The code in question is allocating a block of memory that the size of the CODES structure, filling it with some data, and returning a pointer to the new block. The data is apparently some operation codes (that is, instructions) for something, so perhaps the data is being sent to some other device where the instructions will be executed.

Get generic type using Mono embedded

How to I create a generic List<String> object using mono embedded calls? I can get List's MonoClass:
MonoClass* list = mono_class_from_name(mscorlibimage,
"System.Collections.Generic", "List`1");
and I see in docs that there's
mono_class_from_generic_parameter(MonoGenericParam*...)
but I have no idea where and how to get the MonoGenericParam. Or perhaps I need to construct a valid name for mono_class_from_name? I think this can be a bit slower but I'd accept that for now. I tried
MonoClass* list = mono_class_from_name(mscorlib::get().image, "System.Collections.Generic", "List`1[System.String]");
but no luck.
UPDATE:
OK I found a way. Still I'd like to see if there's an official way of doing thing, as this hack looks too dirty to me.
Basically I searched mono sources for generic methods and found mono_class_bind_generic_parameters (see https://raw.github.com/mono/mono/master/mono/metadata/reflection.c). I had to link to libmono-2.0.a in addition to .so to use it. But it worked:
extern "C" MonoClass*
mono_class_bind_generic_parameters(MonoClass *klass,
int type_argc, MonoType **types, bool is_dynamic);
MonoClass* list = mono_class_from_name(mscorlib::get().image,
"System.Collections.Generic", "List`1");
MonoClass* strcls = mono_class_from_name(mscorlib::get().image, "System", "String");
printf("str class: %p\n", strcls);
MonoType* strtype = mono_class_get_type(strcls);
printf("str type: %p\n", strtype);
MonoType* types[1];
types[0] = strtype;
list = mono_class_bind_generic_parameters(list, 1, types, false);
printf("list[string] class: %p\n", list);
MonoObject* obj = mono_object_new(domain, list);
printf("list[string] created: %p\n", obj);
I suppose I can take sources (UPDATE: hardly so) of these methods and reimplement them (they parse metadata, etc) - if I don't want to link to .a - but I wonder if there's a simpler way. Mono docs just don't answer anything, as they use to.
UPDATE: found this thread: http://mono.1490590.n4.nabble.com/Embedded-API-Method-signature-not-found-with-generic-parameter-td4660157.html which seems to say that no embedded API exists for what I want (i.e. they do not bother to expose mono_class_bind_generic_parameters). Can someone prove that it's correct? With that method, by the way, I get MonoReflectionType* and no way to get back MonoType* from it - while it is as easy to as getting ->type from the structure - which is internal and access via functions to it is internal. Mono Embedded should be called "Mono Internal" instead.
UPDATE: another method is to hack mono_class_inflate_generic_type using copy of internal structures:
struct _MonoGenericInst {
uint32_t id; /* unique ID for debugging */
uint32_t type_argc : 22; /* number of type arguments */
uint32_t is_open : 1; /* if this is an open type */
MonoType *type_argv [1];
};
struct _MonoGenericContext {
/* The instantiation corresponding to the class generic parameters */
MonoGenericInst *class_inst;
/* The instantiation corresponding to the method generic parameters */
void *method_inst;
};
_MonoGenericInst clsctx;
clsctx.type_argc = 1;
clsctx.is_open = 0;
clsctx.type_argv[0] = mono_class_get_type(System::String::_SClass());
MonoGenericContext ctx;
ctx.method_inst = 0;
ctx.class_inst = &clsctx;
MonoType* lt = mono_class_inflate_generic_type(
mono_class_get_type(System::Collections::Generic::List<System::String>::_SClass()),
&ctx);
This doesn't require static link to .a but is even a worse hack. And mono_class_inflate_generic_type is marked as DEPRECATED - so, if this is deprecated, then which is the modern one?
In many cases a mono embedding conundrum can be resolved by using a managed helper method. This is the approach used here.
So we have:
A managed helper method that accepts a generic type definition and an array of generic parameter types.
A client method that accepts a generic type definition name (e.g.: System.Collections.Generic.List`1), an assembly image that contains the type (or use an Assembly Qualified name) and an object of the required generic parameter type. We retrieve the underlying monoType for the object.
Note that when passing type info into the managed layer it has to be an instance of MonoReflectionType as obtained from mono_type_get_object().
The managed helper method is trivial and does the actual instantiation:
public static object CreateInstanceOfGenericType(Type genericTypeDefinition, Type[] parms)
{
// construct type from definition
Type constructedType = genericTypeDefinition.MakeGenericType(parms);
// create instance of constructed type
object obj = Activator.CreateInstance(constructedType);
return obj;
}
The helper code is called, in this case, from Objective-C:
+ (id)createInstanceOfGenericTypeDefinition:(char *)genericTypeDefinitionName monoImage:(MonoImage *)monoImage itemObject:(id)itemObject
{
// get the contained item monoType
MonoType *monoType = [DBType monoTypeForMonoObject:[itemObject monoObject]];
MonoReflectionType *monoReflectionType = mono_type_get_object([DBManagedEnvironment currentDomain], monoType);
// build a System.Array of item types
DBManagedObject *argType = [[DBManagedObject alloc] initWithMonoObject:(MonoObject *)monoReflectionType];
NSArray *argTypes = #[argType];
DBSystem_Array *dbsAargTypes = [argTypes dbsArrayWithTypeName:#"System.Type"];
// get the generic type definition
//
// Retrieves a MonoType from given name. If the name is not fully qualified,
// it defaults to get the type from the image or, if image is NULL or loading
// from it fails, uses corlib.
// This is the embedded equivalent of System.Type.GetType();
MonoType *monoGenericTypeDefinition = mono_reflection_type_from_name(genericTypeDefinitionName, monoImage);
// create instance using helper method
MonoMethod *helperMethod = [DBManagedEnvironment dubrovnikMonoMethodWithName:"CreateInstanceOfGenericType" className:"Dubrovnik.FrameworkHelper.GenericHelper" argCount:2];
void *hargs [2];
hargs[0] = mono_type_get_object([DBManagedEnvironment currentDomain], monoGenericTypeDefinition);
hargs[1] = [dbsAargTypes monoArray]; // a monoArray *
MonoObject *monoException = NULL;
MonoObject *monoObject = mono_runtime_invoke(helperMethod, NULL, hargs, &monoException);
if (monoException) NSRaiseExceptionFromMonoException(monoException);
id object = [System_Object subclassObjectWithMonoObject:monoObject];
return object;
}
For the complete code see Dubrovnik on Github

A program that will let the user input a string and then output each letter on a new line

import java.util.Scanner;
public class Program3_5
{
public static void main (String[]args)
{
Scanner scan = new Scanner(System.in);
String input = new String();
System.out.println("Please enter a string: ");
input=scan.next();
int length;
length = input.length;
input.substring();
System.out.println(charAt(0));
while (length)
{
System.out.println(charAt(0 + 1));
}
}
}
I am getting an error stating that it "cannot find symbol - variable length"
I have tried numerous things yet I am having trouble getting it to work. New to Java! Thanks in advance.
For example if the user were to input: Hello There
The Output would print the letters on separate lines.
String#length() is a method, not a field, of String. You need to call the method. In Java, methods are called (or "invoked") using parentheses. So, change
length = input.length;
// to
length = input.length();
Anticipating the next compile error you see:
while (length)
won't compile in Java because length is an int, but the condition part of a while must be a boolean. I'm guessing you want to continue as long as the string is not empty, so change the while condition to be
while (length > 0)
Other problems you'll need to solve to get your code to compile:
String#substring() requires integer arguments
Also, the code will compile with the String input = new String(); but the assignment is completely unnecessary. In Java, you almost never need to new a string. Instead, use string literals.

How do I express a void method call as the result of DynamicMetaObject.BindInvokeMember?

I'm trying to give a short example of IDynamicMetaObjectProvider for the second edition of C# in Depth, and I'm running into issues.
I want to be able to express a void call, and I'm failing. I'm sure it's possible, because if I dynamically call a void method using the reflection binder, all is fine. Here's a short but complete example:
using System;
using System.Dynamic;
using System.Linq.Expressions;
class DynamicDemo : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression expression)
{
return new MetaDemo(expression, this);
}
public void TestMethod(string name)
{
Console.WriteLine(name);
}
}
class MetaDemo : DynamicMetaObject
{
internal MetaDemo(Expression expression, DynamicDemo demo)
: base(expression, BindingRestrictions.Empty, demo)
{
}
public override DynamicMetaObject BindInvokeMember
(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Expression self = this.Expression;
Expression target = Expression.Call
(Expression.Convert(self, typeof(DynamicDemo)),
typeof(DynamicDemo).GetMethod("TestMethod"),
Expression.Constant(binder.Name));
var restrictions = BindingRestrictions.GetTypeRestriction
(self, typeof(DynamicDemo));
return new DynamicMetaObject(target, restrictions);
}
}
class Test
{
public void Foo()
{
}
static void Main()
{
dynamic x = new Test();
x.Foo(); // Works fine!
x = new DynamicDemo();
x.Foo(); // Throws
}
}
This throws an exception:
Unhandled Exception:
System.InvalidCastException: The
result type 'System.Void' of the
dynamic binding produced by the object
with type 'DynamicDemo' for the binder
'Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder'
is not compatible with the result type 'System.Object' expected by the
call site.
If I change the method to return object and return null, it works fine... but I don't want the result to be null, I want it to be void. That works fine for the reflection binder (see the first call in Main) but it fails for my dynamic object. I want it to work like the reflection binder - it's fine to call the method, so long as you don't try to use the result.
Have I missed a particular kind of expression I can use as the target?
This is similar to:
DLR return type
You do need to match the return type specified by the ReturnType property. For all of the standard binaries this is fixed to object for almost everything or void (for the deletion operations). If you know you're making a void call I'd suggest wrapping it in:
Expression.Block(
call,
Expression.Default(typeof(object))
);
The DLR used to be quite lax about what it would allow and it would provide some minimal amount of coercion automatically. We got rid of that because we didn't want to provide a set of convensions which may or may not have made sense for each language.
It sounds like you want to prevent:
dynamic x = obj.SomeMember();
There's no way to do that, there'll always be a value returned that the user can attempt to continue to interact with dynamically.
I don't like this, but it seems to work; the real problem seems to be the binder.ReturnType coming in oddly (and not being dropped ("pop") automatically), but:
if (target.Type != binder.ReturnType) {
if (target.Type == typeof(void)) {
target = Expression.Block(target, Expression.Default(binder.ReturnType));
} else if (binder.ReturnType == typeof(void)) {
target = Expression.Block(target, Expression.Empty());
} else {
target = Expression.Convert(target, binder.ReturnType);
}
}
return new DynamicMetaObject(target, restrictions);
Perhaps the callsite expects null to be returned but discards the result - This enum looks interesting, particularly the "ResultDiscarded" flag...
[Flags, EditorBrowsable(EditorBrowsableState.Never)]
public enum CSharpBinderFlags
{
BinaryOperationLogical = 8,
CheckedContext = 1,
ConvertArrayIndex = 0x20,
ConvertExplicit = 0x10,
InvokeSimpleName = 2,
InvokeSpecialName = 4,
None = 0,
ResultDiscarded = 0x100,
ResultIndexed = 0x40,
ValueFromCompoundAssignment = 0x80
}
Food for thought...
UPDATE:
More hints can be gleaned from Microsoft / CSharp / RuntimeBinder / DynamicMetaObjectProviderDebugView which is used (I presume) as a visualizer for debuggers. The method TryEvalMethodVarArgs examines the delegate and creates a binder with the result discarded flag (???)
Type delegateType = Expression.GetDelegateType(list.ToArray());
if (string.IsNullOrEmpty(name))
{
binder = new CSharpInvokeBinder(CSharpCallFlags.ResultDiscarded, AccessibilityContext, list2.ToArray());
}
else
{
binder = new CSharpInvokeMemberBinder(CSharpCallFlags.ResultDiscarded, name, AccessibilityContext, types, list2.ToArray());
}
CallSite site = CallSite.Create(delegateType, binder);
... I'm at the end of my Reflector-foo here, but the framing of this code seems a bit odd since the TryEvalMethodVarArgs method itself expects an object as a return type, and the final line returns the result of the dynamic invoke. I'm probably barking up the wrong [expression] tree.
-Oisin
The C# binder (in Microsoft.CSharp.dll) knows whether or not the result is used; as x0n (+1) says, it keeps track of it in a flag. Unfortunately, the flag is buried inside a CSharpInvokeMemberBinder instance, which is a private type.
It looks like the C# binding mechanism uses ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded (a property on an internal interface) to read it out; CSharpInvokeMemberBinder implements the interface (and property). The job appears to be done in Microsoft.CSharp.RuntimeBinder.BinderHelper.ConvertResult(). That method has code that throws if the aforementioned ResultDiscarded property doesn't return true if the type of the expression is void.
So it doesn't look to me like there's an easy way to tease out the fact that the result of the expression is dropped from the C# binder, in Beta 2 at least.