I'm trying to use jason-io to serialize/deserialize MyClass instances. The jason-io library has two classes, JsonWriter and JsonReader which respectively perform serialization and deserialization. Both operations are invoked from a Grails controller.
During serialization a JSON object containing, among other things, class names is created. Deserialization fails at Class.forName("...MyClass"). The class name is correct.
I've traced the problem and found that the class loader of MyClass is a (java.net) URLClassLoader, but the JsonReader class loader is a (org.codehaus.groovy.grails.cli.support) GrailsRootLoader. I don't know how to fix this, though.
Thanks
This may be linked to a known issue in groovy. The solution in that bug report is to specify the class loader:
def file = new File('thingy.txt')
file.withObjectInputStream(getClass().classLoader){ ois ->
def yourObject = ois.readObject ( )
}
The withObjectInputStream method is available in groovy on other classes too, for example I used this successfully with an instance of GZIPInputStream.
Related
Upgrading a legacy system of grails. One of the controllers implements Serializable. This is throwing the following error in newer versions of grails:
Invalid duplicate class definition of class com.regional.ScheduleController :
The source contains at least two definitions of the class.
One of the classes is an explicit generated class using the class statement,
the other is a class generated from the script body based on the file name.
Solutions are to change the file name or to change the class name.
The solution mentioned would break (previous) grails convention. Anyone know how to handle this in grails 2.5+?
EDIT
Serializable is not the issue. I tried removing it and got the same error.
I found this explanation from another question:
IN groovy.. class B{} is a class structure and defines a class B.
Scripts are classes too.
Now you may create a B.groovy, with the content "class B{}; def b = new B()".
There would be one class named B, and a script with the very same name.
This is a conflict.
However this does not explain why it runs fine below grails 2.5 and not above it. And I can't find a def conflict like the one mentioned above in that controller.
ANSWER:
One of the imports was what was actually failing- in a way that caused groovy to generate a class definition based on the current file name. When it hit the class definition, there was already an auto generated class name to collide with.
certainly I have not read something fundamental, and it seems very strange, but I wonder.
Suppose you use
#SharedPref
public interface SharedPreferencesInterface {
#DefaultBoolean(true)
boolean showDeviceName();
I have the IDE (idea) configured with Gradle, and I generated the SharedPreferencesInterface_ class that I can use in another class as
#Pref
SharedPreferencesInterface_ prefs;
But suppose someone now download the project, how can the use? Because the class where used SharedPreferencesInterface_ not compile because the class does not exist, and the class does not exist because compilation errors ...
How it's made? Surely there is a way ... configured to compile certain classes first?
Help is appreciated.
A greeting.
But suppose someone now download the project, how can the use? Because
the class where used SharedPreferencesInterface_ not compile because
the class does not exist, and the class does not exist because
compilation errors ...
This is the same situation when you compile a project in a full build (when no classes are generated yet). Actually Gradle always does a full build currently in Android projects. No configuration is needed at all in addition to the standard AndroidAnnotaions config.
Actually this works because the compiler does not fully compiles your class before passing it to annotations processing. It is clear it should not to, because the class may reference generated classes, which are only available after the processing. So first the compiler creates a model of the classes, only parses the structure of the them (fields, methods, return types, parameter types, etc), but not the implementations. Also it allows missing types even on fields. If it finds a missing type, it assigns to TypeKind.ERROR, but the name of the type is still available for the annotation processor. After the processor is done, it generates the missing class, so the kind of the class is no longer TypeKind.ERROR, and the compilation can succeed.
I need to do some custom data binding and I tried to use the #BindUsing annotation on a class (http://grails.org/doc/latest/api/org/grails/databinding/BindUsing.html), however, it's being ignored. I am under the assumption that since the annotation is used on the class that would mean that every time a data binding happens and that class is involved, the BindingHelper class would be used, but it's never actually called. Is there something that I'm missing or doing wrong?
Here's the class definition where UserBinding is a class that implements the BindingHelper interface:
#BindUsing(UserBinding)
class User extends SomeOtherClass
{
...
Also am I correct in understanding that basically creating a ValueConverter and using #BindUsing on a class accomplish the same thing?
BindUsing on a class is not used often and there seems to be a bug reported around that already. [From the link] The problem could be that there are multiple request parameters with the same name it might be using the helper only for the first one.
Using a property level #BindUsing annotation should be simpler to implement and is less likely to fail (even when there are multiple entries in the params map with the same name).
I have a loop in my controller that does something like this:
for(d in grailsApplication.domainClasses) {
def c = d.getClazz().count()
// construct table containing object instance counts
}
My intent is to use this loop to count the instances of non-leaf domain classes in my database. Is there a way to query the domain class itself to find out if it is abstract or not? I wasn't sure if there were some member functions automatically added by the framework since I am still new to Groovy/Grails. I couldn't find anything that addressed it in the Grails documentation.
Figured it out after a few minutes of poking around the Groovy documentation. The function isAbstract() can be invoked on the domain class to determine whether or not the domain class is a leaf node in the class hierarchy
I was wondering if anyone had an idea for the best way to provide the
functionality of bindData() outside of my grails controllers. In my current
project I have created several groovy classes to model objects returned by
an api. In these classes I have a static method that parses xml and returns
a List of objects of the class. I would like to skip all the type casting
nonsense by using the bindData method in these classes. Any suggestions on
how to do this would be appreciated.
I was looking for a similar solution, to use bindData in a service class. I found a solution in JT's blog. The solution is basically to import:
import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod
then add this to your code:
def foo = new Foo()
BindDynamicMethod bind = new BindDynamicMethod()
def args = [ foo, params, [exclude:['name', 'mail']] ] // for example
bind.invoke( foo, 'bind', (Object[])args)
The (Object[]) cast is necessary du to Groovy/Java compatability. (Groovy is treating the ‘args’ object as an ArrayList, not an array of Objects.)