Re: Problems moving JsInterop from GWT 2.7 to 2.8

2024-04-15 Thread Marco Tenti (IoProgrammo88)
" I also solved the problem of List and Map with an own Interface, which is 
an ArrayList/HashMap on serverside and an own implemented native List/Map 
on gwt side" can you share the solution ?

Il giorno venerdì 29 settembre 2017 alle 14:00:12 UTC+2 Ignacio Baca 
Moreno-Torres ha scritto:

> We have been using this technique for more than a year and it works 
> perfectly. We call it "Java Notation Object", hehe and you should 
> understand the limitations, which more or less you are currently 
> fulfilling. Just a few changes...
>
> The most important, yes, you should use 
> @JsType(isNative=true,namespace=GLOBAL,name="Object"), so you are actually 
> ignoring any kind of typing, so this is more a "scheme" of where to find 
> things than an actual typed object. This is pretty important! This is 
> pretty similar to JSON but in Java, and these classes are not actually Java 
> classes, are just a scheme. All these limitations are the common 
> intersection of the feature between Java and JS.
>
> You can do some tricks to use collections but we end up removing all of 
> them and using arrays instead. But, to make it easy to work with, we added 
> some @JsOverlay to return or set the Collection. For example if you have 
> "String[] roles" you can add "@JsOverlay getRoleSet() { return 
> Stream.of(roles).collecto(toSet()); }". Overlays are ok bc there are just 
> like extension method or static method, so no behavior is added to the 
> object.
>
> This work perfectly on both sides, but there is a small annoying 
> difference between GWT and Java, in java new Foo() will initialize 
> primitive types and in GWT (js) will not. So we never use constructor 
> directly, in the kind of classes we always add a static factory method and 
> we initialize any non-nullable field, even primitives! So in java you are 
> actually creating the object of the specified type, but in JS you are just 
> calling "new Object()", but it is ok, bc where are using a scheme, no a 
> type. And we never use instanceof on these schemes! This will work on the 
> Java side, but I strongly discourage, you should not need to do that.
>
> Finally, we never use getter and setter, don't make sense, you "cannot use 
> inheritance" (you can use with some ticks too, for example using some int 
> or string field as the type indicator and using, for example, the visitor 
> pattern to traverse, this is what actually people need to do in JS so, no 
> magic just the common intersection of features between java and json), 
> almost everything is like final and you must not add behavior, so it is 
> much explicit and easier to just make all field public.
>
> I think the first you should do is removing getters and setters, and add 
> @JsType(native,Object) to all your types, this refactor can be done almost 
> instantly in your IDE (inline method). Then stop using Collection might not 
> be so easy to refactor. So you might continue using it either using 
> overlays or creating a custom jsinterop-compatible type. In this case, I 
> recommend to not to use the whole java.util API bc it will force you to 
> export the whole API and use generateJsInteropExports. If you are really 
> interested or need help there just ask, but just try out avoiding maps, and 
> using arrays. Anyways, the "Map/List own interface" should work too, just 
> neet to make it work.
>
> On Fri, Sep 29, 2017 at 12:53 PM Thomas Broyer  wrote:
>
>>
>>
>> On Friday, September 29, 2017 at 11:09:42 AM UTC+2, Jürgen Beringer wrote:
>>>
>>> Hey,
>>>
>>> currently  I tried the 2. time to move our application from gwt 2.7 to 
>>> gwt 2.8, but I have big problems with the changes of JsInterop.
>>>
>>> The application contains a serverside java part, running in a jetty and 
>>> the client part, build with gwt, so I can reuse many software on server and 
>>> client side. (It is the main part of the website  www.spreadshirt.com )
>>> To use also the same data classes (containing only fields with getter 
>>> and setter, no other methods) on both sides, I used JsInterop and it works 
>>> very well with gwt 2.7 and exchanged the data as json.
>>>
>>> Example Data class:
>>>
>>> @JsType
>>> public class MyObject {
>>> private String id;
>>> 
>>> @JsProperty
>>> public String getId() {
>>> return id;
>>> }
>>> @JsProperty
>>> public void setId(String id) {
>>> this.id = id;
>>> }
>>> }
>>>
>>>
>>> The class can be used on server side like any normal java class with any 
>>> REST Framework. On gwt side I was able to convert a transmitted json to the 
>>> class with:
>>>
>>>
>>> MyObject myObject = getJsTypeObject(JsonUtils.safeEval(jsonString));
>>> //use getter and setter to access fields
>>>
>>> public static native  T getJsTypeObject(JavaScriptObject result)/*-{
>>> return result;
>>> }-*/;
>>>
>>>
>>> And to create Objects on gwt side and send them to the server as json:
>>>
>>> MyObject myObject = new MyObject();
>>> myObject.setId("1");
>>> String 

Re: Problems moving JsInterop from GWT 2.7 to 2.8

2017-09-29 Thread Ignacio Baca Moreno-Torres
We have been using this technique for more than a year and it works
perfectly. We call it "Java Notation Object", hehe and you should
understand the limitations, which more or less you are currently
fulfilling. Just a few changes...

The most important, yes, you should use
@JsType(isNative=true,namespace=GLOBAL,name="Object"), so you are actually
ignoring any kind of typing, so this is more a "scheme" of where to find
things than an actual typed object. This is pretty important! This is
pretty similar to JSON but in Java, and these classes are not actually Java
classes, are just a scheme. All these limitations are the common
intersection of the feature between Java and JS.

You can do some tricks to use collections but we end up removing all of
them and using arrays instead. But, to make it easy to work with, we added
some @JsOverlay to return or set the Collection. For example if you have
"String[] roles" you can add "@JsOverlay getRoleSet() { return
Stream.of(roles).collecto(toSet()); }". Overlays are ok bc there are just
like extension method or static method, so no behavior is added to the
object.

This work perfectly on both sides, but there is a small annoying
difference between GWT and Java, in java new Foo() will initialize
primitive types and in GWT (js) will not. So we never use constructor
directly, in the kind of classes we always add a static factory method and
we initialize any non-nullable field, even primitives! So in java you are
actually creating the object of the specified type, but in JS you are just
calling "new Object()", but it is ok, bc where are using a scheme, no a
type. And we never use instanceof on these schemes! This will work on the
Java side, but I strongly discourage, you should not need to do that.

Finally, we never use getter and setter, don't make sense, you "cannot use
inheritance" (you can use with some ticks too, for example using some int
or string field as the type indicator and using, for example, the visitor
pattern to traverse, this is what actually people need to do in JS so, no
magic just the common intersection of features between java and json),
almost everything is like final and you must not add behavior, so it is
much explicit and easier to just make all field public.

I think the first you should do is removing getters and setters, and add
@JsType(native,Object) to all your types, this refactor can be done almost
instantly in your IDE (inline method). Then stop using Collection might not
be so easy to refactor. So you might continue using it either using
overlays or creating a custom jsinterop-compatible type. In this case, I
recommend to not to use the whole java.util API bc it will force you to
export the whole API and use generateJsInteropExports. If you are really
interested or need help there just ask, but just try out avoiding maps, and
using arrays. Anyways, the "Map/List own interface" should work too, just
neet to make it work.

On Fri, Sep 29, 2017 at 12:53 PM Thomas Broyer  wrote:

>
>
> On Friday, September 29, 2017 at 11:09:42 AM UTC+2, Jürgen Beringer wrote:
>>
>> Hey,
>>
>> currently  I tried the 2. time to move our application from gwt 2.7 to
>> gwt 2.8, but I have big problems with the changes of JsInterop.
>>
>> The application contains a serverside java part, running in a jetty and
>> the client part, build with gwt, so I can reuse many software on server and
>> client side. (It is the main part of the website  www.spreadshirt.com )
>> To use also the same data classes (containing only fields with getter and
>> setter, no other methods) on both sides, I used JsInterop and it works very
>> well with gwt 2.7 and exchanged the data as json.
>>
>> Example Data class:
>>
>> @JsType
>> public class MyObject {
>> private String id;
>>
>> @JsProperty
>> public String getId() {
>> return id;
>> }
>> @JsProperty
>> public void setId(String id) {
>> this.id = id;
>> }
>> }
>>
>>
>> The class can be used on server side like any normal java class with any
>> REST Framework. On gwt side I was able to convert a transmitted json to the
>> class with:
>>
>>
>> MyObject myObject = getJsTypeObject(JsonUtils.safeEval(jsonString));
>> //use getter and setter to access fields
>>
>> public static native  T getJsTypeObject(JavaScriptObject result)/*-{
>> return result;
>> }-*/;
>>
>>
>> And to create Objects on gwt side and send them to the server as json:
>>
>> MyObject myObject = new MyObject();
>> myObject.setId("1");
>> String jsonString = stringify(myObject);
>>
>>
>> public static final native String stringify(Object result) /*-{
>> return JSON.stringify(result);
>> }-*/;
>>
>>
>> I also solved the problem of List and Map with an own Interface, which is
>> an ArrayList/HashMap on serverside and an own implemented native List/Map
>> on gwt side.
>>
>> The application has more than 100 such Objects which are heavily used on
>> server and client side in many methods which are also be used on both
>> sides

Re: Problems moving JsInterop from GWT 2.7 to 2.8

2017-09-29 Thread Thomas Broyer


On Friday, September 29, 2017 at 11:09:42 AM UTC+2, Jürgen Beringer wrote:
>
> Hey,
>
> currently  I tried the 2. time to move our application from gwt 2.7 to gwt 
> 2.8, but I have big problems with the changes of JsInterop.
>
> The application contains a serverside java part, running in a jetty and 
> the client part, build with gwt, so I can reuse many software on server and 
> client side. (It is the main part of the website  www.spreadshirt.com )
> To use also the same data classes (containing only fields with getter and 
> setter, no other methods) on both sides, I used JsInterop and it works very 
> well with gwt 2.7 and exchanged the data as json.
>
> Example Data class:
>
> @JsType
> public class MyObject {
> private String id;
> 
> @JsProperty
> public String getId() {
> return id;
> }
> @JsProperty
> public void setId(String id) {
> this.id = id;
> }
> }
>
>
> The class can be used on server side like any normal java class with any 
> REST Framework. On gwt side I was able to convert a transmitted json to the 
> class with:
>
>
> MyObject myObject = getJsTypeObject(JsonUtils.safeEval(jsonString));
> //use getter and setter to access fields
>
> public static native  T getJsTypeObject(JavaScriptObject result)/*-{
> return result;
> }-*/;
>
>
> And to create Objects on gwt side and send them to the server as json:
>
> MyObject myObject = new MyObject();
> myObject.setId("1");
> String jsonString = stringify(myObject);
>
>
> public static final native String stringify(Object result) /*-{
> return JSON.stringify(result);
> }-*/;
>
>
> I also solved the problem of List and Map with an own Interface, which is 
> an ArrayList/HashMap on serverside and an own implemented native List/Map 
> on gwt side.
>
> The application has more than 100 such Objects which are heavily used on 
> server and client side in many methods which are also be used on both 
> sides. So implementing them twice for server and client side would be a big 
> overhead.
> Now is my question, how can I convert this gwt 2.7 code to gwt 2.8 (mainly 
> to be able to use Java8 syntax in future). I tried multiple variants, but 
> it seems for me, JsInterop in gwt 2.8 is not planned for such usecases 
> which were possible in gwt 2.7 withou any problems.
> I can either use a native Javascript Object in gwt (native=true) or a in 
> GWT created Object in Javascript. But I see no solution to do both with the 
> same Type. 
>
> I get 2 Problems
>
>- Casting issues: I can't use native=true because I also want to 
>create such Objects on gwt side, so on every assignment (jsonString to 
>typed variable) I get a cast exception and at least in superdev mode I 
>can't deactivate the cast exceptions
>
> If you never do "instanceof" (or expect cast exceptions) on client-side, 
you could probably use isNative=true,namespace=GLOBAL,name="Object"; that 
way, all your objects are plain old JS objects (no specific 
class/constructor is generated in JS), which is actually exactly what you'd 
expect from JSON.parse().

>
>- field name problems: The jsonString of the last example is 
>{"id_g_$3":"1"} and not {"id":"1"} because the JsProperty for getter and 
>setter works only fine with native objects. If I add JsProperty to the 
>field itself, I can't do have JsProperty for the getter and setter, so I 
>have to add JsIgnore to them. But then when I work with native Objects I 
>can't use the getter and setter on gwt side. I would need JsProperty on 
>getter, setter and the field itself, but this is also not allowed.
>
>
The "id_g_$3" is probably because you don't -generateJsInteropExports; 
contrary to 2.7, in 2.8, the "don't obfuscate @JsProperty/@JsMethod names" 
only applies when you -generateJsInteropExports.
But if you switch to isNative=true,namespace=GLOBAL,name="Object", you 
don't even need it.

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.


Problems moving JsInterop from GWT 2.7 to 2.8

2017-09-29 Thread Jürgen Beringer
Hey,

currently  I tried the 2. time to move our application from gwt 2.7 to gwt 
2.8, but I have big problems with the changes of JsInterop.

The application contains a serverside java part, running in a jetty and the 
client part, build with gwt, so I can reuse many software on server and 
client side. (It is the main part of the website  www.spreadshirt.com )
To use also the same data classes (containing only fields with getter and 
setter, no other methods) on both sides, I used JsInterop and it works very 
well with gwt 2.7 and exchanged the data as json.

Example Data class:

@JsType
public class MyObject {
private String id;

@JsProperty
public String getId() {
return id;
}
@JsProperty
public void setId(String id) {
this.id = id;
}
}


The class can be used on server side like any normal java class with any 
REST Framework. On gwt side I was able to convert a transmitted json to the 
class with:


MyObject myObject = getJsTypeObject(JsonUtils.safeEval(jsonString));
//use getter and setter to access fields

public static native  T getJsTypeObject(JavaScriptObject result)/*-{
return result;
}-*/;


And to create Objects on gwt side and send them to the server as json:

MyObject myObject = new MyObject();
myObject.setId("1");
String jsonString = stringify(myObject);


public static final native String stringify(Object result) /*-{
return JSON.stringify(result);
}-*/;


I also solved the problem of List and Map with an own Interface, which is 
an ArrayList/HashMap on serverside and an own implemented native List/Map 
on gwt side.

The application has more than 100 such Objects which are heavily used on 
server and client side in many methods which are also be used on both 
sides. So implementing them twice for server and client side would be a big 
overhead.
Now is my question, how can I convert this gwt 2.7 code to gwt 2.8 (mainly 
to be able to use Java8 syntax in future). I tried multiple variants, but 
it seems for me, JsInterop in gwt 2.8 is not planned for such usecases 
which were possible in gwt 2.7 withou any problems.
I can either use a native Javascript Object in gwt (native=true) or a in 
GWT created Object in Javascript. But I see no solution to do both with the 
same Type. 

I get 2 Problems

   - Casting issues: I can't use native=true because I also want to create 
   such Objects on gwt side, so on every assignment (jsonString to typed 
   variable) I get a cast exception and at least in superdev mode I can't 
   deactivate the cast exceptions
   - field name problems: The jsonString of the last example is 
   {"id_g_$3":"1"} and not {"id":"1"} because the JsProperty for getter and 
   setter works only fine with native objects. If I add JsProperty to the 
   field itself, I can't do have JsProperty for the getter and setter, so I 
   have to add JsIgnore to them. But then when I work with native Objects I 
   can't use the getter and setter on gwt side. I would need JsProperty on 
   getter, setter and the field itself, but this is also not allowed.
   
   
Is there any solution for me? I love the idea to run the same code in a 
normal java webapplication and to compile it gwt to run it on client side 
(the gwt compiler produces very optimized js code and support code 
splitting, remote logging with java stacktraces and debugging on live 
website with superdev). I don't want to compile java code to js to run it 
with nodejs on serverside.

Thanks a lot, 
Jürgen
 


-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.