Git Product home page Git Product logo

parceler's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parceler's Issues

NPE when unwrapping null Parcel field

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

how to build and run a helloworld project using parceler?

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 ?

ParcelableAnalysis#findFields includes static fields

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.

No corresponding property found for constructor parameter nodes

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?

StackOverflowError with @Parcel Enum

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"
}

Interest in static factory

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.

Stack trace/error readability

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  

org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for java.util.Collections$UnmodifiableRandomAccessList

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.

org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for com.example.projects.Foo

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.

Problem with @ParcelClass annotations and related classes

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)

Don't require setters or empty constructor

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.

Access to CREATOR

How does one get an access to Creator object of a class annotated with @Parcel?

External Configuration

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{
//...
}

Parceler crashes when running

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'
}

Does not work because of javax.annotations.Nonnull in dependent JAR

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

Class not found when unmarshalling: org.parceler.NonParcelRepository$MapParcelable

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

Generic class support

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?

Annotation processor does not work with Android Gradle build

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?

Unable to create ParcelableFactory exception

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.

NullPointerException when building app with maven

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

Field converter sample

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.

wrap fails for null Boolean feed

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")});

IncompatibleClassChangeError when building my transfuse project

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)

Nested class not included in @ParcelClasses

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....

Usage of parceler (@Parcel) with Realm.io (Android)

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;
  }

support wrapping and unwrapping of list and array types

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));

Add field name in warnings

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.

Compiler warns about private static fields requiring reflection.

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).

Errors with inheritance and contructors

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.

Parcel.unwrap()

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

ClassNotFoundException: android.os.Parcel when using @ParcelClass

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?

Annotation processing is stuck in eclipse

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.

Incorrect warning for final fields

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?

Errors with arrays as constructor parameters

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.

Compile error: cannot find symbol parcel$$3 .writeParcelable(model$$2 .field, flags);

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

Compatibility Issues with Project Lombok / hrisey

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)

ClassNotFoundException when using Parceler with savedInstanceState

Steps to reproduce:

  • Use Parcels.wrap() in onSaveInstanceState() method of a Fragment (from v4 support lib),
  • Use Parcels.unwrap() in onActivityCreated() of the same Fragment.

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).

Ignore static (and maybe final) variables

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

Support List type

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.

List of @Parcel

serialize and deserialize @Parcel annotated classes using the appropriate Parcelable representation via either Parcels.get(example) or direct instantiation: new Example$$Parcelable(example).

Gradle and Parceler causing "Unable to create ParcelableFactory"?

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?

cryptic error with inherited classes?

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 @Parcel 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..

No ability to suppress reflection required messages

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.