j256 / ormlite-android

ORMLite Android functionality used in conjunction with ormlite-core
http://ormlite.com/
ISC License
1.59k stars 367 forks source link

Caused by: java.lang.IllegalArgumentException: Could not find appropriate get method for private XXX.id #53

Closed jianinz closed 8 years ago

jianinz commented 8 years ago

Hi,

I am encountering this exception which i don't understand.

Caused by: java.lang.IllegalArgumentException: Could not find appropriate get method for private 
java.lang.String com.xx.xx.xx.json.XXX.id

In my XXX pojo, getId method was defined, so i don't understand why this happens, anyone could shed some light on it?

    @DatabaseField(columnName = Table.Columns.ID, id = true, useGetSet = true, unique = true)
    private String id;

    public String getId() {
        return aggregateStart.getTime() + "-" + aggregateEnd.getTime() + "-" + aggregateInterval;
    }

    public void setId(final String id) {
        this.id = id;
    }

is id not allowed as String instead of int? or getId cannot return concatenated string? Thanks!

j256 commented 8 years ago

Any chance the class is not static or not public or something? Are those methods in a base class or the entity class itself?

jianinz commented 8 years ago

Thanks for input. But not really, it's not a base class, neither static. any other suggestions?

j256 commented 8 years ago

Is this an inner class?

jianinz commented 8 years ago

no, it's not. Although the column annotation in id is a static class, but i am not sure that is what you referred to @DatabaseField(columnName = Table.Columns.ID, id = true, useGetSet = true, unique = true)

j256 commented 8 years ago

Huh. I'm stumped. I was asking about inner classes and the like because reflection can't see the methods unless the inner class is static and visible. Can you whittle down your entity and post it to pastebin.com or something? I'd like to see if I can reproduce it.

jianinz commented 8 years ago

Sure, thanks

http://pastebin.com/Kyd7QPxT

j256 commented 8 years ago

This passes for me: http://pastebin.com/fcJfXJuB You will need to replace your connection-source with your real one.

jianinz commented 8 years ago

Thanks. In our productuon app, we have found only few users had experienced this crash. I never experienced this crash neither myself.

j256 commented 8 years ago

I'm going to close but feel free to re-open if you get more information.

jianinz commented 8 years ago

alright, thanks!

jianinz commented 8 years ago

think i have found something. If json entity has been obfuscated by proguard, this could happen. By prevent from happening, just add the following in the proguard

-keep public class com.app.example.foo.bar.ReportSummary {
    public protected private *;
}

I guess since we enable useGetSet = true in the annotation, so it tries to find id via reflection in the runtime, but get method was obfuscated

joezorry commented 8 years ago

@jianinz good find.

jianinz commented 8 years ago

Thanks @joezorry :)

rAseri commented 8 years ago

Hi guys, i'm faced with same issue. In our dev envirenment all works fine, but on production we have some users with crashes: java.lang.IllegalArgumentException: Could not find appropriate get method for private XXX.id. This issue happens only on Samusung devices, but i'm tested app on Samsung Galaxy S5 and it's works fine. I can't even simulate this crach and I don't understand how to fix it.

I'm also tried to edit my proguard file how @jianinz recommended but its not working

This is carchlytics logs: http://crashes.to/s/13fc0337145 This is part of my POJO class: http://pastebin.com/D37AF8ZB

jianinz commented 8 years ago

Hi @rAseri , the previous solution did not work out for me neither, sorry, i forgot to update my answer. In the end, i did a workaround, instead of doing following

    @DatabaseField(columnName = Table.Columns.ID, id = true, useGetSet = true, unique = true)
    private String id;

    public String getId() {
        return aggregateStart.getTime() + "-" + aggregateEnd.getTime() + "-" + aggregateInterval;
    }

    public void setId(final String id) {
        this.id = id;
    }

i don't use useGetSet annotation anymore, so to avoid reflection. I used normal incremental id


    @DatabaseField(columnName = ID, index = true, generatedId = true)
    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(final Integer id) {
        this.id = id;
    }

and just add another column to do your customization

lostmsu commented 8 years ago

I experience this bug on some machines as well, but only on fields, which start with 'i' (v4.31). I guess it has something to do with first letter capitalization not being language-neutral. @j256, can you reopen the bug, considering this input?

j256 commented 8 years ago

Aha. Ok. I think I've fixed this by adding a DatabaseType.upCaseEntityName() with the default implementation using: entityName.toUpperCase(Locale.ENGLISH); See: https://github.com/j256/ormlite-core/commit/8ccc75d7479f33ea99f8b0a3bed3b934ecdd757c