johncarl81 / parceler Goto Github PK
View Code? Open in Web Editor NEW:package: Android Parcelables made easy through code generation.
Home Page: http://parceler.org
License: Apache License 2.0
:package: Android Parcelables made easy through code generation.
Home Page: http://parceler.org
License: Apache License 2.0
Warning:(25, 24) Parceler: Reflection is required to modify private field: String secret, consider using non-private.
Warning:(25, 24) Parceler: Reflection is required to access private field: String secret, consider using non-private.
I am already using transient
on static fields, but I am using @Parcel
on a class that I am also using with GSON for serialisation, so I can't add transient to the private fields as that has a different meaning in GSON (it will not serialise the field).
I am using the private
access level by design, so I want to be able to suppress this warning. Could you advise me how to do this?
Say I have a class that looks like this(In a library that I don't have control of):
public class Foo{
public Bar[] bars;
public static class Bar{
//...
}
}
If I annotate them using
@ParcelClass(Foo.class)
The compiler complains about not able to serialize Bar
If I do it like this:
@ParcelClasses({@ParcelClass(Foo.class), @ParcelClass(Foo.Bar.class)})
Everything works perfectly.
I am totally fine with the current way of doing it, but I thought an enhancement like auto detecting all the nested classes would be nice too.
PS:
From memory, I think we have to use CompoundReference
or something like that....
It would be really nice if the library would be able to use the constructor method or simply set the fields. This would allow immutable objects and also make it closer to how Gson behaves.
I want to make my data immutable so this is what I did:
....
private final HashMap<String, Bundle> nodes;
....
@ParcelConstructor
NavigationPath(HashMap<String, Bundle> nodes) {
this.nodes = nodes;
}
HashMap<String, Bundle> getNodes() {
return nodes;
}
Notice that the constructor and getter for node is package private.
This exception is thrown when compiling:
NavigationPath.java:40: error: Parceler: No corresponding property found for constructor parameter nodes
NavigationPath(HashMap<String, Bundle> nodes) {
If I make the methods/constructors public, then I loose immutability.
Can you make parceler support at least package private visibility?
Butterknife does that without problems so I assume this can be done?
Could you make this error a bit more explanatory? :-)
Execution failed for task ':app:compileDebugJava'.
> org.androidtransfuse.TransfuseAnalysisException: @Parcel code generation did not complete successfully.
I got it trying to use it with an abstract class hierarchy...something like:
@Parcel
abstract class A {
int field1;
int field2;
}
@Parcel
class B extends A {
String fields
//etc.
}
And marked class B
as @Parcel
only initially since I wouldn't try parceling class A
. I tried adding @Parce
l to class A
w/o luck.
It'd help if it printed out how far it got parceling so we could get a bit more of a clue as to what field or class it's having a hard time with :-P
It's probably also a good idea to add a hierarchy class as an example on the site too..
How does one get an access to Creator object of a class annotated with @Parcel
?
Currently java.util.List is supported by the framework, and I think it is a must for this to be a must for every android application.
I know that TypeErasure gets on the way, but maybe we can have some special approach.
I am trying to use parceler with a generic class I defined, this is a simplified example:
@Parcel
public class ParcelableObject {
ParcelableInner<Integer> parcelableInner;
}
@Parcel
public class ParcelableInner<T> {
T i;
}
Running it I get an exception:
Exception in thread "pool-177-thread-2" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write java.lang.Object
So I create a Converter to manual define how to convert the inner class:
@Parcel
@ParcelClass(value = ParcelableInner.class, converter = ParcelableInnerConverter.class)
public class ParcelableObject {
ParcelableInner<Integer> parcelableInner;
}
public class ParcelableInner<T> {
T i;
}
But I get a different error:
Exception in thread "pool-185-thread-1" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write it.cosenonjaviste.ParcelableInner
This error seems to be related to generic definition, so I removed the generic:
@Parcel
@ParcelClass(value = ParcelableInner.class, converter = ParcelableInnerConverter.class)
public class ParcelableObject {
ParcelableInner parcelableInner;
}
public class ParcelableInner {
Object i;
}
And the error is the first one again:
Exception in thread "pool-194-thread-1" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write java.lang.Object
In my opinion the last example is valid, I am using a converter so the framework validation is not needed. What do you think? Is there a different solution to use generic classes?
Add a sample showing how to get parceler working with Android Studio and Gradle.
Would anyone like to see Parceler integrate with Google's Autovalue? Unfortunately there are some caveats...
I was curious if Parceler could integrate with AutoValue (https://github.com/google/auto/tree/master/value) to make for super simple Parcelables. What was required was to introduce an alternative way to build a @Parcel
bean, namely through a static factory method. By annotating this method with @ParcelFactory
, Parceler will pick it up and use it as an alternative to the constructor. Here's what the current working api looks like:
@AutoValue
@Parcel
public abstract class ExampleParcel {
@ParcelProperty("message")
public abstract String getMessage();
@ParcelFactory
public static ExampleParcel create(@ParcelProperty("message") String message) {
return new AutoValue_ExampleParcel(message);
}
}
There are a couple of rough edges here:
First, Parceler's default serialization mode relies on fields. Because the fields in the AutoValue generated bean AutoValue_ExampleParcel
are final, writing to them is problematic.
Second, Parceler's method serialization mode follows the java bean get/set syntax. Parceler will only use getter and setters that are properly named (get_, set_) and are public and have the two in pairs. Of course with AutoValue's goal of writing immutable beans, this is not possible, thus we need to use the @ParcelProperty
for every static factory input / getter pair (yes, very verbose).
Third, AutoValue produces a class (AutoValue_ExampleParcel
) that is package private. Unless this class resides in the org.parceler
package, then it cannot be mapped to the Parceler$$Parcels
class and thus will not be available via the Parcels.wrap()
utility method. The alternative is to reference the generated Parcelable class like so:
intent.putExtra(EXTRA_EXAMPLE_PARCEL, new ExampleParcel$$Parcelable(exampleParcel));
These seem like the only problems that arise with this mapping. I have to say, I like the promise of this, but it ends up being very verbose to map between the two technologies. Would anyone like this functionality to be integrated into Parceler?
The implementation of this is on the staticfactory branch.
Getting errors with latest. Issue isn't present on 0.2.10.
Beans to be enhanced by the annotation processor may not exist in the current compile pass (ie: in an external library or from code generation). Therefore, we need a way to configure Parceler to find these classes.
The idea is to add an annotation that Parceler will recognize:
@ParcelClass(Example.class)
Since this annotation doesn't rely on the class that it annotates, this configuration can appear anywhere. Perhaps on the Application
class or some other convenient configuration point:
@ParcelClass(Example.class)
public class SomeApplication extends Application{
//...
}
I have these annotations
@ParcelClasses({
@ParcelClass(A.class),
@ParcelClass(B.class)
})
Where B
has a List<A>
member. I get this exception:
Exception in thread "pool-10-thread-1" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write A
at org.parceler.internal.Generators.getGenerator(Generators.java:49)
at org.parceler.internal.generator.ListReadWriteGenerator.generateReader(ListReadWriteGenerator.java:82)
at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:223)
at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:191)
at org.parceler.internal.ParcelableGenerator.generateParcelable(ParcelableGenerator.java:118)
at org.parceler.internal.ExternalParcelTransactionWorker.innerRun(ExternalParcelTransactionWorker.java:63)
at org.parceler.internal.ExternalParcelTransactionWorker.innerRun(ExternalParcelTransactionWorker.java:37)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
In warnings like this:
warning: Parceler: Reflection is required to modify private final fields, consider using non-private.
warning: Parceler: Reflection is required to access private fields, consider using non-private.
Can we add the field name?
Something like this:
private int count;
private final int theAnswer = 42;
warning: Parceler: [on field "count"]Reflection is required to modify private fields, consider using non-private.
warning: Parceler: [on field "theAnswer"]Reflection is required to access private final fields, consider using non-private.
Because my external library has hundreds of final/static fields and finding them all is taking forever.
It seems that class fields need to be public in order to parceler work. Is it right?
Can't we use getter/setter methods instead?
Can you provide a sample on how to specify a field converter?
For instance, I have an entity which has, among other fields, a field of type org.joda.time.DateTime. How do I specify how to parcel/unparcel this field? Is it possible? I know about ParcelConverter but I don't want to specify how to parcel all my other fields.
Thanks for making this great library available to all.
12-02 15:18:53.531: E/AndroidRuntime(1768): Caused by: java.lang.NoClassDefFoundError: org.parceler.Parcels
Hi John,
Thanks for all that you do in this project. I really want to use it but I've been having trouble getting it to run on even a blank app.
I'm using Android Studio 0.4.4 and created a brand new project. The only thing I did was go into File -> Project Structure -> Modules -> Dependencies and added Parceler there. I've added 0.2.6 and 0.2.7, with or without the API and no order matters.
Looking through the Verbose logs don't reveal anything interesting other than the program simply stops running.
Any ideas?
build.gradle
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion '19.0.0'
defaultConfig {
minSdkVersion 7
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
compile 'org.parceler:parceler:0.2.6@jar'
}
I have the following code which produces the error: Error:Parceler: Unable to find read/write generator for type io.realm.Realm for io.realm.RealmObject.realm
It was working all fine without extends RealmObject
, however I want to use Realm to put to database easily. Is there a way to exlcude the RealmObject fields and just use the basic pojo fields for @parcel?
@Parcel
public class Feed extends RealmObject{
int id;
public String text;
public String time_created;
String time_modified;
int comments_count;
int likes_count;
String feed_type;
int obj_id;
String image;
String user_name;
String user_earthmile_points;
boolean liked;
boolean commented;
boolean is_private;
String url;
int feed_creator_id;
}
When I try to @Parcel
an enum, I get a StackOverflowError.
Here is my test Parcelable class...
@Parcel
public class ParcelableClass {
public String someString;
public int someInt;
public Type type;
@Parcel
public enum Type {
TYPE_A,
TYPE_B,
TYPE_C
}
}
Here is my parceling code where it blows up...
public class MyActivity extends Activity {
...
@Override
protected void onSaveInstanceState(Bundle outState) {
ParcelableClass parcelableObject = new ParcelableClass();
parcelableObject.someString = "test";
parcelableObject.someInt = 5;
parcelableObject.type = ParcelableClass.Type.TYPE_B;
outState.putParcelable("keyParcelableClass", Parcels.wrap(parcelableObject));
super.onSaveInstanceState(outState);
}
...
}
And this is the stacktrace...
09-09 22:17:19.567 32393-32393/com.example.ahuang.helloworld E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.ahuang.helloworld, PID: 32393
java.lang.StackOverflowError
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:79)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahuang_helloworld_ParcelableClass$Type(ParcelableClass$$Parcelable.java:80)
at com.example.ahuang.helloworld.ParcelableClass$$Parcelable.writecom_example_ahu
Note, when I don't set the parcelableObject.type = ParcelableClass.Type.TYPE_B;
, it works fine; I'm able to unparcel it, and the type
field is null.
I have the following in my build.gradle
...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.parceler:parceler-api:0.2.12"
provided "org.parceler:parceler:0.2.12"
}
How about support for IcePick style storing/restoring of parcelable classes?
https://github.com/frankiesardo/icepick
Because of the extra wrapping step, IcePick is currently incompatible with parceler (if I'm not mistaken)
The support for inheritance that was added in 0.2.7 does not work very well with constructors.
For example, this causes an error:
@Parcel
public class AClass {
String message;
public final String getMessage() { return this.message; }
public void setMessage(String message) { this.message = message; }
public AClass(String message) {
this.message = message;
}
}
@Parcel
public class ASubClass extends AClass {
int status;
public int getStatus() { return status; }
public void setStatus(int status) { this.status = status; }
public ASubClass(String message, int status) {
super(message);
this.status = status;
}
}
As far as I can tell, this i caused by the way the hierarchy loop works in ParcelableAnalysis
. The loop starts at the subclass and collect it's fields and properties. Then it collect the constructor and attempts to validate the properties, but as the message
property is defined by the parent, it cannot be validated at this state.
If the hierarchy loop were oriented the other way around, so that it started with the base class, then I think i would be easier to get this inheritance working.
I have a Boolean field in my parcel which can sometimes be null...
the generated code fails with an NPE:
parcel$$1 .writeBooleanArray(new boolean[] {InjectionUtil.getField(java.lang.Boolean.class, com.company.ValueObject.class, valueObject$$0, "isFeatured")});
Getting this when trying to build the app with Maven:
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ app ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding MacRoman, i.e. build is platform dependent!
[INFO] Compiling 28 source files to /Users/[path]/android/app/target/classes
Exception in thread "pool-3-thread-1" java.lang.NullPointerException
at com.sun.tools.javac.model.JavacElements.cast(JavacElements.java:627)
at com.sun.tools.javac.model.JavacElements.getPackageOf(JavacElements.java:362)
at org.androidtransfuse.adapter.element.ASTElementFactory.buildPackageClass(ASTElementFactory.java:130)
at org.androidtransfuse.adapter.element.ASTElementFactory.buildType(ASTElementFactory.java:87)
at org.androidtransfuse.adapter.element.ASTElementFactory.getType(ASTElementFactory.java:78)
at org.parceler.internal.ReloadableASTElementFactory$ReloadableASTTypeProvider.get(ReloadableASTElementFactory.java:66)
at org.parceler.internal.ReloadableASTElementFactory$ReloadableASTTypeProvider.get(ReloadableASTElementFactory.java:54)
at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:52)
at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:34)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
POM dependencies:
<dependency>
<groupId>org.parceler</groupId>
<artifactId>parceler</artifactId>
<version>0.2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.parceler</groupId>
<artifactId>parceler-api</artifactId>
<version>0.2.5</version>
</dependency>
This looks like it could be related to: johncarl81/transfuse#69
I'm not sure whether this is intentional or not but I'll report it anyway :)
Basically, anything that is not an ArrayList
would get exceptions like this, for example, stuff returned from:
Collections.unmodifiableList()
ArrayList.subList(start, end)
Just to name a few....
Even though the returned value still implements List
...
In README.md, List
wast part of the supported types
This problem can be easily solved by wrapping the List
with ArrayList
's copy constructor.
Got a strange case here:
I'm trying to save a HashMap<String, String
in a Bundle
along with some other stuff...
Bundle bundle = new Bundle();
HashMap<String, String> map = new HashMap<>();
map.put("a", "b");
bundle.putParcelable("foo", Parcels.wrap(map));
bundle.putInt("foo1", 42);
// and putting many other stuff
The bundle then gets put into another map:
HashMap<String, Bundle> nodes = new HashMap<>();
nodes.put("bar", bundle);
// and putting many more bundles...
nodes
is part of a data object structured like this:
@Parcel
public class MyData {
HashMap<String, Bundle> nodes = new HashMap<>();
}
an instance of MyData gets saved into Bundle :
myBundle.putParcelable("baz", Parcels.wrap(myData));
the myBundle
gets passed around in Activities and Fragments.....
at some point in time, I would retrieve some of the values in myBundle
, and it's working for the stuff that isn't wrapped in a Parcel.wrap()
MyData data = Parcels.unwrap( myBundle.getParcelable(baz));
Bundle bundle data.nodes.get("bar");
HashMap<String, String> map = Parcels.unwrap(bundle.getParcelable("foo")); // fails
int myInt = bundle.getInt("foo1"); // works
Here's the stacktrace
java.lang.ClassNotFoundException: org.parceler.NonParcelRepository$MapParcelable
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:305)
at java.lang.Class.forName(Class.java:269)
at android.os.Parcel.readParcelableCreator(Parcel.java:2133)
at android.os.Parcel.readParcelable(Parcel.java:2097)
at android.os.Parcel.readValue(Parcel.java:2013)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
at android.os.Bundle.unparcel(Bundle.java:249)
at android.os.Bundle.getParcelable(Bundle.java:1206)
// getParcelable()'s calling class is here
// ........
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.parceler.NonParcelRepository$MapParcelable" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:305)
at java.lang.Class.forName(Class.java:269)
at android.os.Parcel.readParcelableCreator(Parcel.java:2133)
at android.os.Parcel.readParcelable(Parcel.java:2097)
at android.os.Parcel.readValue(Parcel.java:2013)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
at android.os.Bundle.unparcel(Bundle.java:249)
at android.os.Bundle.getParcelable(Bundle.java:1206)
// .......
Suppressed: java.lang.ClassNotFoundException: org.parceler.NonParcelRepository$MapParcelable
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 29 more
Caused by: java.lang.NoClassDefFoundError: Class "Lorg/parceler/NonParcelRepository$MapParcelable;" not found
... 33 more
This whole thing reminds me of not setting the ClassLoader
for a Parcelable
object, which causes strange crashes before I started using Parceler
I've set up build.gradle according to the example. Everything compiles fine but when I run the app an invoke Parcels.wrap, the app crashes. The project is set up with android-apt plugin and AndroidAnnotations which both are working fine.
org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for sg.ruqqq.test.Item
E/AndroidRuntime(30134): at org.parceler.Parcels$ParcelCodeRepository.get(Parcels.java:182)
E/AndroidRuntime(30134): at org.parceler.Parcels.wrap(Parcels.java:69)
Any help?
Would be nice to overload the wrap()
method to support the following:
public static <T> Parcelable[] wrap(T[] input)
public static <T> ArrayList<Parcelable> wrap(List<T> input)
public static <T> SparseArray<Parcelable> wrap(SparseArray<T> input)
This way the API can be used directly on collections of Parcelables e.g.:
bundle.putParceableArrayList(Parcels.wrap(myArrayListOfObjects));
Sometimes, we have a external library were @ParcelClass
doesn't work very well.
Is it possible to introduce something like Mixins in the Jackson JSON library?
Here are the docs:
http://wiki.fasterxml.com/JacksonMixInAnnotations
With a public static final String
I see this warning:
Warning:(10, 30) Gradle: Parceler: Reflection is required to modify final field: String REQUEST_CODE, consider using non-private.
Is there any circumstance in which someone would want a static final field to be parceled? Or any static field, for that matter?
I'm interesting in using parceler in my android project. I've read the introduction and some of the issues, but I am still unable to setup a simple helloworld project to run. It seems that the problem is no annotation class is generated.
Can anybody write an entry level manual to show, step by step, how to setup a helloworld project using parceler, with the IDE eclipse or IntelliJ ?
If I have a Parcel
with another child Parcel
field that's null, I get NPEs during unwrap
.
Ideally this should just set the field to null instead of trying to unmarshall a null object.
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object org.parceler.ParcelWrapper.getParcel()' on a null object reference
example:
@Parcel
public static class Parent {
Child child;
}
@Parcel
public static class Child {
// ...
}
unwrapping a parent with a null child will cause NPE
I have some static final
constants defined in one of my Parcel
classes that's causing errors on serialization
error: cannot assign a value to final variable STATUS_OFFLINE
I just came across this library, it looks nice. I haven't used it yet, but from looking at the front page example:
Example example = ((ParcelableWrapper<Example>)wrapped).getParcel();
example.getName(); // Andy
example.getAge(); // 42
The unsafe generic cast could be hidden away into a Parcel.unwrap()
method. Something along these lines:
public final class Parcels {
public static <T> Parcelable unwrap(Parcelable input) {
ParcelableWrapper<T> wrapper = (ParcelableWrapper<T>) input;
return wrapper.getParcel();
}
}
Then the calling code would be more sexy:
Example example = Parcels.unwrap(wrapped);
example.getName(); // Andy
example.getAge(); // 42
I use eclipse to develop and build my projects. From the command line, i can compile with maven, but unfortunately eclipse cannot do that. The annotation processing is started, but somewhere it is stuck. I debugged the processing, and i made it to TransactionProcessorPool.execute()
. Here the ExecutorService.execute()
method is called, but the execution is stuck at ExecutorService.awaitTermination()
. I guess the Transaction
goes into a forever loop or something. Unfortunately i could not debug it any deeper.
I am using eclipse 4.3.2 on Windows 8. This is the sample project what i used.
Steps to reproduce:
Desired effect:
Reference to unmarshalled object returned from unwrap().
Current behavior:
Exception thrown: BadParcelableException: ClassNotFoundException when unmarshalling: [my_class]$$Parcelable
The $$Parcelable classes are created during build; the correct types are mapped in Parceler$$Parcels class. Problem does not appear when using custom Bundle instances (they use a BootClassLoader by default) or passing in an Intent (where the extras bundle uses a PathClassLoader). Checked on Nexus 5 with Android 4.4, Nexus 4 with 4.4.2, (both with ART runtime), Galaxy S3 (4.3.1, dalvik).
serialize and deserialize @Parcel
annotated classes using the appropriate Parcelable representation via either Parcels.get(example)
or direct instantiation: new Example$$Parcelable(example)
.
I'm testing parceler library. Thanks for great works.
But I got compiler error when I used Parcelable
object in 2nd depth.
Here's the my code.
@Parcel
public class TestModel {
public static transient final int DUMP = 1010;
int i;
boolean b;
long l;
TestSubModel subModel;
public static class TestParcelable implements Parcelable {
int i;
public TestParcelable() {
}
public TestParcelable(android.os.Parcel source) {
i = source.readInt();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(android.os.Parcel dest, int flags) {
dest.writeInt(i);
}
public static final Parcelable.Creator<TestParcelable> CREATOR = new Parcelable.Creator<TestParcelable>() {
@Override
public TestParcelable createFromParcel(android.os.Parcel source) {
return new TestParcelable(source);
}
@Override
public TestParcelable[] newArray(int size) {
return new TestParcelable[size];
}
};
}
@Parcel
public static class TestSubModel {
TestParcelable testParcelable;
}
public TestModel() {
}
public TestModel(int i) {
this.i = i;
}
}
Here's the output from gradle.
TestModel$$Parcelable.java:58: error: cannot find symbol
parcel$$3 .writeParcelable(testSubModel$$2 .testParcelable, flags);
^
symbol: variable flags
location: class TestModel$$Parcelable
1 error
Which jars do you need to drop in the libs folder to make this work?
I got an external library(jar) that has an Apple:
public class Apple {
// this is for example only
public int count = 1024;
public String name = "Macintosh";
public int[] balls = { 12, 2, 3 };
}
I need to use the Apple in my Fragment:
@ParcelClass(Apple.class) // assume Apple properly imported
public class AppleFragment extends Fragment{
//...
private Apple myApple;
//...
}
If I compile the app
gradle assembleDebug
the compiler complains:
//....
// everything before this is normal
:app:compileDebugJava
Exception in thread "pool-22-thread-1" java.lang.NoClassDefFoundError: android/os/Parcel
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
at java.lang.Class.getDeclaredMethods(Class.java:1962)
at org.androidtransfuse.adapter.classes.ASTClassFactory.buildType(ASTClassFactory.java:119)
at org.androidtransfuse.adapter.classes.ASTClassFactory.getType(ASTClassFactory.java:72)
at org.androidtransfuse.adapter.classes.ASTClassFactory.buildType(ASTClassFactory.java:109)
at org.androidtransfuse.adapter.classes.ASTClassFactory.getType(ASTClassFactory.java:72)
at org.androidtransfuse.adapter.classes.ASTClassFactory.getType(ASTClassFactory.java:63)
at org.parceler.internal.ExternalParcelTransactionWorker.getConverterType(ExternalParcelTransactionWorker.java:78)
at org.parceler.internal.ExternalParcelTransactionWorker.innerRun(ExternalParcelTransactionWorker.java:69)
at org.parceler.internal.ExternalParcelTransactionWorker.innerRun(ExternalParcelTransactionWorker.java:36)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
at org.androidtransfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: android.os.Parcel
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 19 more
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
// everything after this is normal
:app:preDexDebug UP-TO-DATE
//....
Parceler is added like this in build.gradle
provided 'org.parceler:parceler:0.2.9'
compile 'org.parceler:parceler-api:0.2.9'
The Apple class is just an example, in reality it happens with any POJO/ simple class with a few string fields. And the strange thing is that the App works(I didn't test whether Parcel actually persists any data) without throwing any exception. The generated class is there and the content look good to me:
From Parceler$$Parcels.java
package org.parceler;
import java.util.HashMap;
import java.util.Map;
import somepackage.Apple;
import somepackage.Apple$$Parcelable;
@Generated(value = "org.parceler.ParcelAnnotationProcessor", date = "2014-05-31T01:33+0800")
public class Parceler$$Parcels
implements Repository<org.parceler.Parcels.ParcelableFactory>
{
private final Map<Class, org.parceler.Parcels.ParcelableFactory> map$$0 = new HashMap<Class, org.parceler.Parcels.ParcelableFactory>();
public Parceler$$Parcels() {
map$$0 .put(Apple.class, new Parceler$$Parcels.Apple$$Parcelable$$0());
}
public Map<Class, org.parceler.Parcels.ParcelableFactory> get() {
return map$$0;
}
private final static class Apple$$Parcelable$$0
implements org.parceler.Parcels.ParcelableFactory<Apple>
{
@Override
public Apple$$Parcelable buildParcelable(Apple input) {
return new Apple$$Parcelable(input);
}
}
}
I'm not so sure about Parceler$$Parcels$Apple$$Parcelable$$0.class though:
package org.parceler;
import somepackage.Apple;
import somepackage.Apple..Parcelable;
final class Parceler$$Parcels$Apple$$Parcelable$$0
implements Parcels.ParcelableFactory<Apple>
{
public Apple..Parcelable buildParcelable(Apple input)
{
return new Apple..Parcelable(input);
}
}
I have a feeling that nothing is actually persisted....
Is there anything that I can do to fix this?
I have a static field on a base class, and ParcelableAnalysis is complaining that it can't find a read/write generator for its type. Given that it's a static field and not an instance member, ParcelableAnalysis shouldn't even be trying. Looks like maybe this will require a transfuse fix.
Not sure if the other member finders exclude class members or not.
Unlike Maven, the Android Gradle build does not put the Android runtime on the annotation processor class path. During build the following exception occurs:
Exception in thread "pool-4-thread-1" java.lang.NoClassDefFoundError: android/os/IBinder
at org.parceler.internal.ParcelableGenerator.setup(ParcelableGenerator.java:290)
at org.parceler.internal.ParcelableGenerator.<init>(ParcelableGenerator.java:88)
at org.androidtransfuse.transaction.Parceler$$TransactionWorker$$Provider$$0.get(Parceler$$TransactionWorker$$Provider$$0.java:61)
at org.androidtransfuse.transaction.Parceler$$TransactionWorker$$Provider$$0.get(Parceler$$TransactionWorker$$Provider$$0.java:19)
at org.androidtransfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:54)
at org.androidtransfuse.transaction.Transaction.run(Transaction.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: android.os.IBinder
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 9 more
A similar issue was fixed in butterknife before
JakeWharton/butterknife#77, maybe this can give some guidance on how to fix it?
It seems that Parceler is currently not compatible with hrisey, a Android specific fork of Project Lombok.
I've set up my domain classes with @Data
, @Value
,@AllArgsConstructor
, @NoArgsConstructor
and @RequiredArgsConstructor
.
When I try to launch the modified app, I get the following StackTrace:
Exception in thread "pool-54-thread-1" java.lang.NullPointerException
at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:148)
at org.parceler.internal.generator.ParcelReadWriteGenerator.generateReader(ParcelReadWriteGenerator.java:54)
at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282)
at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234)
at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166)
at org.parceler.internal.ParcelableGenerator.generateParcelable(ParcelableGenerator.java:100)
at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:55)
at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:35)
at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.parceler.transfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47)
at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35)
at org.parceler.transfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55)
at org.parceler.transfuse.transaction.Transaction.run(Transaction.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
I'm not yet using parceler in my project, but I am using transfuse and will eventually be using parceler... So I do have the parceler stuff in my tool chain, and I just started getting these exceptions... I have no problems building if I comment out the parceler deps..
I have no clue where the issue is occurring... there is no context for the error.
Caused by: java.lang.IncompatibleClassChangeError: Implementing class
at org.parceler.ParcelAnnotationProcessor$$Bootstrap.inject(ParcelAnnotationProcessor$$Bootstrap.java:42)
at org.parceler.ParcelAnnotationProcessor$$Bootstrap.inject(ParcelAnnotationProcessor$$Bootstrap.java:19)
at org.parceler.ParcelAnnotationProcessor.init(ParcelAnnotationProcessor.java:57)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:517)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:614)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:707)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
Hi,
I found this project very promising but I'm not able to use it as I'm dependent on other projects using com.google.code.findbugs:jsr305:1.3.9
in their dependencies.
And it conflicts with javax.annotations.Nonnull
in transfuse-bootstrap jar and DEX is not able to compile such a project.
Please remove this class form your project and use external dependcy instead.
Thanks
Would it be possible to log the class caused generation to fail to appear at the top of the stack trace or in the error message?
The current error message is:
Unable to find appropriate Parcel method to write java.lang.Object
I'd love to see
Unable to find appropriate Parcel method to write java.lang.Object in com.test.myclass
Here's the output from ./gradlew assembleDebug --stacktrace
FAILURE: Build failed with an exception. at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282) * What went wrong: Execution failed for task ':app:compileDebugJava'. at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234) at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166) > org.parceler.transfuse.TransfuseAnalysisException: @Parcel code generation did not complete successfully. at org.parceler.internal.generator.ParcelReadWriteGenerator.generateReader(ParcelReadWriteGenerator.java:63) at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282) * Try: at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234) at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166) Run with --info or --debug option to get more log output. at org.parceler.internal.ParcelableGenerator.generateParcelable(ParcelableGenerator.java:100) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:54) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:34) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.parceler.transfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.parceler.transfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55) at org.parceler.transfuse.transaction.Transaction.run(Transaction.java:77) * Exception is: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744) Exception in thread "pool-9-thread-3" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write java.lang.Object at org.parceler.internal.Generators.getGenerator(Generators.java:49) at org.parceler.internal.generator.MapReadWriteGenerator.generateReader(MapReadWriteGenerator.java:90) at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282) at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234) at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166) org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:compileDebugJava'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:289) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63) at org.parceler.internal.ParcelableGenerator.generateParcelable(ParcelableGenerator.java:100) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$1.run(DefaultTaskPlanExecutor.java:33) at org.gradle.internal.Factories$1.create(Factories.java:22) at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:198) at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:266) at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:135) at org.gradle.api.internal.changedetection.state.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:95) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:31) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:86) at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61) at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:54) at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67) at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54) at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:166) at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113) at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81) at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:64) at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33) at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:35) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26) at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50) at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:201) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:174) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:34) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:170) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.parceler.transfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:139) at org.parceler.transfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33) at org.parceler.transfuse.transaction.Transaction.run(Transaction.java:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22) at org.gradle.launcher.Main.doAction(Main.java:46) Exception in thread "pool-9-thread-2" org.parceler.ParcelerRuntimeException: Unable to find appropriate Parcel method to write java.lang.Object at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45) at org.parceler.internal.Generators.getGenerator(Generators.java:49) at org.gradle.launcher.Main.main(Main.java:37) at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50) at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32) at org.gradle.launcher.GradleMain.main(GradleMain.java:23) at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30) at org.parceler.internal.generator.MapReadWriteGenerator.generateReader(MapReadWriteGenerator.java:90) at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127) at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282) at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:55) Caused by: java.lang.RuntimeException: org.parceler.transfuse.TransfuseAnalysisException: @Parcel code generation did not complete successfully. at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234) at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166) at org.parceler.internal.generator.ParcelReadWriteGenerator.generateReader(ParcelReadWriteGenerator.java:63) at org.parceler.internal.ParcelableGenerator.buildReadFromParcelExpression(ParcelableGenerator.java:282) at com.sun.tools.javac.main.Main.compile(Main.java:553) at org.parceler.internal.ParcelableGenerator.buildReadFromParcel(ParcelableGenerator.java:234) at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:45) at org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler.execute(Jdk6JavaCompiler.java:38) at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:96) at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:49) at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:35) at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:29) at org.parceler.internal.ParcelableGenerator.buildParcelRead(ParcelableGenerator.java:166) at org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler.execute(DelegatingJavaCompiler.java:20) at org.gradle.api.internal.tasks.compile.IncrementalJavaCompilerSupport.execute(IncrementalJavaCompilerSupport.java:33) at org.gradle.api.internal.tasks.compile.IncrementalJavaCompilerSupport.execute(IncrementalJavaCompilerSupport.java:24) at org.gradle.api.tasks.compile.Compile.compile(Compile.java:67) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219) at org.parceler.internal.ParcelableGenerator.generateParcelable(ParcelableGenerator.java:100) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:54) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201) at org.parceler.internal.ParcelTransactionWorker.innerRun(ParcelTransactionWorker.java:34) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.parceler.transfuse.transaction.CodeGenerationScopedTransactionWorker.innerRun(CodeGenerationScopedTransactionWorker.java:47) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533) at org.parceler.transfuse.transaction.AbstractCompletionTransactionWorker.run(AbstractCompletionTransactionWorker.java:35) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61) ... 52 more Caused by: org.parceler.transfuse.TransfuseAnalysisException: @Parcel code generation did not complete successfully. at org.parceler.internal.ParcelProcessor.checkForErrors(ParcelProcessor.java:82) at org.parceler.transfuse.transaction.ScopedTransactionWorker.run(ScopedTransactionWorker.java:55) at org.parceler.transfuse.transaction.Transaction.run(Transaction.java:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744) at org.parceler.ParcelAnnotationProcessor.process(ParcelAnnotationProcessor.java:71) at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794) at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$200(JavacProcessingEnvironment.java:91) at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.runContributingProcs(JavacProcessingEnvironment.java:627) at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1033) at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1198) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1173) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:859) at com.sun.tools.javac.main.Main.compile(Main.java:523) ... 72 more BUILD FAILED
i.e:
Parceler: Reflection is required to modify private final fields, consider using non-private.
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
I could be wrong about this, but I'm not sure static fields would need to be touched when parceling up objects?
In my case, I could just make them public I guess, since they're final as well (they're constants).
In the latest release (and maybe earlier releases) the is some kind of problem with using arrays as constructor parameters.
For instance, this test fails unexpectedly (both the array and the integer values become garbage):
@RunWith(RobolectricTestRunner.class)
public class ArrayTest {
@Test
public void testIntArray() {
IntArrayClass prewrap = new IntArrayClass();
prewrap.setI(10);
prewrap.setArr(new int[] { 1,2,3,4,5 });
IntArrayClass unwrapped = Parcels.unwrap(ParcelsTestUtil.wrap(prewrap));
assertEquals(10, unwrapped.i);
assertArrayEquals(new int[]{1, 2, 3, 4, 5}, unwrapped.getArr());
}
@Parcel(Parcel.Serialization.METHOD)
public static class IntArrayClass {
int[] arr;
int i;
@ParcelConstructor
public IntArrayClass(int i, int[] arr) {
this.arr = arr;
this.i = i;
}
public IntArrayClass() {}
public int[] getArr() { return arr; }
public void setArr(int[] arr) { this.arr = arr; }
public int getI() { return i; }
public void setI(int i) { this.i = i; }
}
}
If I remove the array, or comment out the constructor annotated with @ParcelConstructor
, then the test passes as expected, so the issue seems to be with using arrays as constructor parameters.
The test also fails with ArrayList instead of a plain int array, so maybe this is a general problem with container types.
Hi johncarl81,
I'm using Parceler on my project but I get the error on title. My configuration is:
Parceler library, version 0.2.10
Gradle plugin, version 0.12+
on build.gradle:
def parcelerVersion = '0.2.10'
dependencies{
compile "org.parceler:parceler-api:${parcelerVersion}"
provided "org.parceler:parceler:${parcelerVersion}"
}
the class Foo is made as following:
@Parcel
public class Foo extends FooParent {
...
}
The FooParent class is a class of an external library used on the project.
I've also tried another configuration, like this:
@ParcelClass(FooParent.class)
public class Foo extends FooParent {
...
}
In both cases, I get mentioned error. Can you give me some help? I find this library very useful and certainly I will use it on other my projects.
PS: another one thing, in my case the configuration of build.gradle
dependencies{
compile "org.parceler:parceler-api:${parcelerVersion}"
apt "org.parceler:parceler:${parcelerVersion}"
}
doesn't work.
I get the following exception:
05-25 14:24:08.722: E/AndroidRuntime(1335): org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for com.example.test.models.Debate
My model:
@Parcel
public class Debate{
public int id;
public int category_id;
public int user_id;
public String title;
public String description;
public String date_human;
public String code;
public String username;
public String comments_count;
public ArrayList<Comment> comments;
public ArrayList<String> user_thumbs;
public void setTitle(String value){
this.title = value;
}
public void setDescription(String value){
this.description = value;
}
public void setUsername(String value){
this.username = value;
}
public void setDateHuman(String value){
this.date_human = value;
}
public void setCommentsCount(String value){
this.comments_count = value;
}
public void setUserThumbs(ArrayList list){
this.user_thumbs = list;
}
public Debate setup(JSONObject item) throws JSONException
{
this.setTitle(item.getString("title"));
this.setDescription(item.getString("description"));
this.setUsername(item.getString("username"));
this.setCommentsCount(item.getString("comments_count"));
this.setDateHuman(item.getString("date_human"));
this.setUserThumbs(Helper.jsonToArrayList(item.getJSONArray("user_thumbs")));
return this;
}
}
Any toughts? Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.