Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLASS_EXTRACTION_ERROR - Don't know how to extract Class from type 'T'. #77

Closed
binarytemple opened this issue Jan 7, 2015 · 20 comments
Closed
Assignees

Comments

@binarytemple
Copy link

Hi there,
When running Javers against the AST classes provided by ETP (Erlang Term Parser) project I provoke a crash in Javers.

The exception is as follows:

Exception in thread "main" JaversException: CLASS_EXTRACTION_ERROR JaVers bootstrap error - Don't know how to extract Class from type 'T'.
    at org.javers.common.reflection.ReflectionUtil.extractClass(ReflectionUtil.java:260)
    at org.javers.core.metamodel.type.TypeMapper.findNearestAncestor(TypeMapper.java:272)
    at org.javers.core.metamodel.type.TypeMapper.infer(TypeMapper.java:249)
    at org.javers.core.metamodel.type.TypeMapper.getJaversType(TypeMapper.java:81)
    at org.javers.core.metamodel.type.TypeMapper.getPropertyType(TypeMapper.java:101)
    at org.javers.core.metamodel.type.TypeMapper.isEntityReferenceOrValueObject(TypeMapper.java:105)
    at org.javers.core.graph.ObjectGraphBuilder$1.apply(ObjectGraphBuilder.java:104)
    at org.javers.core.graph.ObjectGraphBuilder$1.apply(ObjectGraphBuilder.java:102)
    at org.javers.core.metamodel.clazz.ManagedClass.getProperties(ManagedClass.java:40)
    at org.javers.core.graph.ObjectGraphBuilder.getSingleReferences(ObjectGraphBuilder.java:102)
    at org.javers.core.graph.ObjectGraphBuilder.buildSingleEdges(ObjectGraphBuilder.java:72)
    at org.javers.core.graph.ObjectGraphBuilder.buildEdges(ObjectGraphBuilder.java:67)
    at org.javers.core.graph.ObjectGraphBuilder.buildGraph(ObjectGraphBuilder.java:55)
    at org.javers.core.graph.LiveGraphFactory.createLiveGraph(LiveGraphFactory.java:27)
    at org.javers.core.GraphFactory.createLiveGraph(GraphFactory.java:30)
    at org.javers.core.diff.DiffFactory.buildGraph(DiffFactory.java:72)
    at org.javers.core.diff.DiffFactory.compare(DiffFactory.java:54)
    at org.javers.core.Javers.compare(Javers.java:110)
    at ETPExampleMain.main(ETPExampleMain.java:25)

As far as I can see, it is choking while reflecting on an instance of the ETPTerm class.

This is a parametrized class, in this case with a signature of:

public abstract class ETPTerm<T> {
    protected T value;

I'm not clear as to whether this is a bug, or something I can work around. Screenshots are from Intellij.

My end goal is to diff AST graphs of Riak configuration files.

Thanks,

Bryan

screen shot 2015-01-07 at 13 20 58
screen shot 2015-01-07 at 13 20 44
screen shot 2015-01-07 at 13 20 30

@binarytemple
Copy link
Author

Forgot to mention, this is with version 1.0.1.

@pszymczyk pszymczyk self-assigned this Jan 7, 2015
@binarytemple
Copy link
Author

From debugging the code, it seems fairly involved. In case you'd like to see what I've been doing, I've shared the project (binarytemple/javers-example) with you. The branch concerned is called etp-attempt. I've left it where it is for now.

@pszymczyk
Copy link
Contributor

Hi, I can't see javers-example repository.

@binarytemple
Copy link
Author

Ah, I'd added bartoszwalacik, added you now - https://github.com/binarytemple/javers-example

@bartoszwalacik
Copy link
Member

thanks for detailed report, w'll see what's going on

@bartoszwalacik
Copy link
Member

I've check your example repo, and cant see the issue.
Could you please give us more details?

(btw I've pushed a fix to your repo, to make it compilable - binarytemple/javers-example@77fa76a)

So you trying to diff objects of class:

public abstract class ETPTerm {
...
}

But what is Your concrete class?

1. NewObject{globalId:'Foo/twochild1'}
2. NewObject{globalId:'Foo/twochild2'}
3. ListChange{globalId:'Foo/head', property:'children', containerChanges:[(1).added:'Foo/twochild1', (2).added:'Foo/twochild2']}

Foo{name='twochild1', children=[]}
Foo{name='twochild2', children=[]}
Foo{name='head', children=[Foo{name='onechild', children=[]}, Foo{name='twochild1', children=[]}, Foo{name='twochild2', children=[]}]}
[NewObject{globalId:'Foo/twochild1'}, NewObject{globalId:'Foo/twochild2'}, ListChange{globalId:'Foo/head', property:'children', containerChanges:[(1).added:'Foo/twochild1', (2).added:'Foo/twochild2']}]changes - NewObject:2 ListChange:1
Process finished with exit code 0

@binarytemple
Copy link
Author

@bartoszwalacik Sorry Bartosz, the problem only manifests when running the class ETPExampleMain on the branch 'etp-attempt'. It produces the following output:

/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/bin/java -Didea.launcher.port=7535 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 14 EAP.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/lib/tools.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/common/javers-example/target/classes:/Users/bryanhunt/.m2/repository/org/javers/javers-core/1.0.1/javers-core-1.0.1.jar:/Users/bryanhunt/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar:/Users/bryanhunt/.m2/repository/org/picocontainer/picocontainer/2.14.3/picocontainer-2.14.3.jar:/Users/bryanhunt/.m2/repository/org/slf4j/slf4j-api/1.7.2/slf4j-api-1.7.2.jar:/Users/bryanhunt/.m2/repository/joda-time/joda-time/2.3/joda-time-2.3.jar:/Users/bryanhunt/.m2/repository/com/github/metadave/etp/0.6-SNAPSHOT/etp-0.6-20131210.173536-1.jar:/Users/bryanhunt/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar:/Users/bryanhunt/.m2/repository/org/antlr/antlr4-runtime/4.0/antlr4-runtime-4.0.jar:/Users/bryanhunt/.m2/repository/org/abego/treelayout/org.abego.treelayout.core/1.0.1/org.abego.treelayout.core-1.0.1.jar:/Users/bryanhunt/.m2/repository/org/erlang/otp/jinterface/1.5.6/jinterface-1.5.6.jar:/Users/bryanhunt/.m2/repository/junit/junit/4.11/junit-4.11.jar:/Users/bryanhunt/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Applications/IntelliJ IDEA 14 EAP.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain ETPExampleMain
[{riak_api,[{pb_ip,"10.239.252.1"},{pb_port,8085}]},{riak_core,[{ring_state_dir,"/data1/data/ring"},{http,[{"99.99.99.1",8091}]},{https,[{"127.0.0.1",8069}]},{ssl,[{certfile,"/etc/riak/cert.pem"},{keyfile,"/etc/riak/key.pem"}]},{cluster_mgr,{"10.239.252.1",9081}},{handoff_port,8099},{platform_bin_dir,"/usr/sbin"},{platform_etc_dir,"/etc/riak"},{platform_lib_dir,"/usr/lib/riak/lib"},{platform_log_dir,"/var/log/riak"},{ring_creation_size,128}]},{riak_kv,[{storage_backend,riak_kv_multi_backend},{pb_ip,"99.99.99.1"},{pb_port,8085},{delete_mode,3000},{multi_backend_default,<<"eleveldb_mult">>},{multi_backend,[{<<"eit_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_eit"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"cli_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_cli"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"pre_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_pre"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"dem_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data/data/leveldb_dem"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"mig_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_mig"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb"},{compression,true},{verify_checksum,true},{sync,false}]}]},{anti_entropy,{on,[]}},{anti_entropy_build_limit,{1,86400000}},{anti_entropy_expire,2592000000},{anti_entropy_concurrency,2},{anti_entropy_tick,15000},{anti_entropy_data_dir,"/data1/data/anti_entropy"},{anti_entropy_leveldb_opts,[{write_buffer_size,4194304},{max_open_files,20},{use_bloomfilter,true}]},{mapred_name,"mapred"},{mapred_system,pipe},{mapred_2i_pipe,true},{mapred_2i_pipe,true},{map_js_vm_count,8},{reduce_js_vm_count,6},{hook_js_vm_count,2},{js_max_vm_mem,8},{js_thread_stack,16},{add_paths,["/foo/","/bar/","/baz/"]},{http_url_encoding,on},{riak_kv_stat,true},{legacy_stats,true},{vnode_vclocks,true},{legacy_keylisting,false},{listkeys_backpressure,true},{fsm_limit,50000},{object_format,v1}]},{riak_search,[{enabled,false}]},{merge_index,[{data_root,"/data1/data/merge_index"},{data_root_2i,"/data1/data/merge_index_2i"},{buffer_rollover_size,1048576},{max_compact_segments,20}]},{bitcask,[{io_mode,erlang},{data_root,"/data1/data/bitcask"}]},{eleveldb,[{data_root,"/data1/data/leveldb"},{compression,true},{verify_checksum,true},{sync,false},{cache_size,134217728}]},{lager,[{handlers,[{lager_console_backend,info},{lager_file_backend,[{"/var/log/riak/error.log",error,10485760,"$D0",5},{"/var/log/riak/console.log",info,10485760,"$D0",5}]}]},{crash_log,"/var/log/riak/crash.log"},{crash_log_msg_size,65536},{crash_log_size,10485760},{crash_log_date,"$D0"},{crash_log_count,5},{error_logger_redirect,true}]},{riak_sysmon,[{process_limit,30},{port_limit,30},{gc_ms_limit,0},{heap_word_limit,40111000},{busy_port,true},{busy_dist_port,true}]},{sasl,[{sasl_error_logger,false}]},{riak_repl,[{fullsync_on_connect,false},{data_root,"/data1/data/riak_repl"},{queue_size,104857600},{server_max_pending,5},{client_ack_frequency,5},{rtq_max_bytes,524288000}]},{riak_jmx,[{enabled,false}]},{snmp,[{agent,[{config,[{dir,"/etc/riak/snmp/agent/conf"},{force_load,true}]},{db_dir,"/data1/data/snmp/agent/db"}]}]},{riak_control,[{enabled,true},{auth,userlist},{userlist,[{"user","pass"}]},{admin,true}]}]
[{riak_api,[{pb_ip,"10.239.252.1"},{pb_port,8085}]},{riak_core,[{ring_state_dir,"/data1/data/ring"},{http,[{"99.99.99.1",8091}]},{https,[{"127.0.0.1",8069}]},{ssl,[{certfile,"/etc/riak/cert.pem"},{keyfile,"/etc/riak/key.pem"}]},{cluster_mgr,{"10.239.252.1",9081}},{handoff_port,8099},{platform_bin_dir,"/usr/sbin"},{platform_etc_dir,"/etc/riak"},{platform_lib_dir,"/usr/lib/riak/lib"},{platform_log_dir,"/var/log/riak"},{ring_creation_size,128}]},{riak_kv,[{storage_backend,riak_kv_multi_backend},{pb_ip,"99.99.99.1"},{pb_port,8085},{delete_mode,3000},{multi_backend_default,<<"eleveldb_mult">>},{multi_backend,[{<<"eit_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_eit"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"cli_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_cli"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"pre_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_pre"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"dem_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data/data/leveldb_dem"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"mig_eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb_mig"},{compression,true},{verify_checksum,true},{sync,false}]},{<<"eleveldb_mult">>,riak_kv_eleveldb_backend,[{data_root,"/data1/data/leveldb"},{compression,true},{verify_checksum,true},{sync,false}]}]},{anti_entropy,{on,[]}},{anti_entropy_build_limit,{1,86400000}},{anti_entropy_expire,2592000000},{anti_entropy_concurrency,2},{anti_entropy_tick,15000},{anti_entropy_data_dir,"/data1/data/anti_entropy"},{anti_entropy_leveldb_opts,[{write_buffer_size,4194304},{max_open_files,20},{use_bloomfilter,true}]},{mapred_name,"mapred"},{mapred_system,pipe},{mapred_2i_pipe,true},{mapred_2i_pipe,true},{map_js_vm_count,8},{reduce_js_vm_count,6},{hook_js_vm_count,2},{js_max_vm_mem,8},{js_thread_stack,16},{add_paths,["/foo/","/bar/","/baz/"]},{http_url_encoding,on},{riak_kv_stat,true},{legacy_stats,true},{vnode_vclocks,true},{legacy_keylisting,false},{listkeys_backpressure,true},{fsm_limit,50000},{object_format,v1}]},{riak_search,[{enabled,false}]},{merge_index,[{data_root,"/data1/data/merge_index"},{data_root_2i,"/data1/data/merge_index_2i"},{buffer_rollover_size,1048576},{max_compact_segments,20}]},{bitcask,[{io_mode,erlang},{data_root,"/data1/data/bitcask"}]},{eleveldb,[{data_root,"/data1/data/leveldb"},{compression,true},{verify_checksum,true},{sync,false},{cache_size,134217728}]},{lager,[{handlers,[{lager_console_backend,info},{lager_file_backend,[{"/var/log/riak/error.log",error,10485760,"$D0",5},{"/var/log/riak/console.log",info,10485760,"$D0",5}]}]},{crash_log,"/var/log/riak/crash.log"},{crash_log_msg_size,65536},{crash_log_size,10485760},{crash_log_date,"$D0"},{crash_log_count,5},{error_logger_redirect,true}]},{riak_sysmon,[{process_limit,30},{port_limit,30},{gc_ms_limit,0},{heap_word_limit,40111000},{busy_port,true},{busy_dist_port,true}]},{sasl,[{sasl_error_logger,false}]},{riak_repl,[{fullsync_on_connect,false},{data_root,"/data1/data/riak_repl"},{queue_size,104857600},{server_max_pending,5},{client_ack_frequency,5},{rtq_max_bytes,524288000}]},{riak_jmx,[{enabled,false}]},{snmp,[{agent,[{config,[{dir,"/etc/riak/snmp/agent/conf"},{force_load,true}]},{db_dir,"/data1/data/snmp/agent/db"}]}]},{riak_control,[{enabled,true},{auth,userlist},{userlist,[{"user","pass"}]},{admin,true}]}]
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" JaversException: CLASS_EXTRACTION_ERROR JaVers bootstrap error - Don't know how to extract Class from type 'T'.
    at org.javers.common.reflection.ReflectionUtil.extractClass(ReflectionUtil.java:260)
    at org.javers.core.metamodel.type.TypeMapper.findNearestAncestor(TypeMapper.java:272)
    at org.javers.core.metamodel.type.TypeMapper.infer(TypeMapper.java:249)
    at org.javers.core.metamodel.type.TypeMapper.getJaversType(TypeMapper.java:81)
    at org.javers.core.metamodel.type.TypeMapper.getPropertyType(TypeMapper.java:101)
    at org.javers.core.metamodel.type.TypeMapper.isEntityReferenceOrValueObject(TypeMapper.java:105)
    at org.javers.core.graph.ObjectGraphBuilder$1.apply(ObjectGraphBuilder.java:104)
    at org.javers.core.graph.ObjectGraphBuilder$1.apply(ObjectGraphBuilder.java:102)
    at org.javers.core.metamodel.clazz.ManagedClass.getProperties(ManagedClass.java:40)
    at org.javers.core.graph.ObjectGraphBuilder.getSingleReferences(ObjectGraphBuilder.java:102)
    at org.javers.core.graph.ObjectGraphBuilder.buildSingleEdges(ObjectGraphBuilder.java:72)
    at org.javers.core.graph.ObjectGraphBuilder.buildEdges(ObjectGraphBuilder.java:67)
    at org.javers.core.graph.ObjectGraphBuilder.buildGraph(ObjectGraphBuilder.java:55)
    at org.javers.core.graph.LiveGraphFactory.createLiveGraph(LiveGraphFactory.java:27)
    at org.javers.core.GraphFactory.createLiveGraph(GraphFactory.java:30)
    at org.javers.core.diff.DiffFactory.buildGraph(DiffFactory.java:72)
    at org.javers.core.diff.DiffFactory.compare(DiffFactory.java:54)
    at org.javers.core.Javers.compare(Javers.java:110)
    at ETPExampleMain.main(ETPExampleMain.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

@bartoszwalacik
Copy link
Member

ok, got it

@binarytemple
Copy link
Author

Also, if it's of use to you, I might be able to help by writing a test-case to reproduce the issue this weekend - I haven't had time to figure out the gradle/intellij interaction/build chain yet.

@bartoszwalacik
Copy link
Member

thanks, the example from the branch 'etp-attempt' is ok

@binarytemple
Copy link
Author

I was able to get a little further in my investigation, this is reasonably challenging stuff. I've attached screenshots of my debugging session, along with explanations for what I was trying. I'm not 100% certain any chance of this type belongs in your codebase, but perhaps you could give me some feedback and let me know if I'm looking in the right places.

This first example just shows looking at the class properties. value' in theabstract class ETPTermis of typeT`. Much information is thrown away. The object in this case is an instance of ETPList<ArrayList> which extends ETPTerm.

screen shot 2015-01-11 at 00 05 59

And then accessing the data in a more complex way. We access the list of declared fields in the superclass, by default value will just be listed as type T... not a lot of use. But if we then take that field and interrogate the instance to determine the value of that field we can get a good idea of the instance type.

screen shot 2015-01-11 at 00 05 12

@bartoszwalacik
Copy link
Member

thanks for that detailed report,
I'm gonna to investigate this case at today afternoon

regards

@bartoszwalacik
Copy link
Member

Hi, situation is quite complex here.

What we know:
Statically you are using abstract generic class:
ETPTerm<T>

In runtime, you are using instances of
ETPList<List<ETPTerm<?>>>

The problem is, that JaVers gets confused while determinig actual type of property
T getValue();

It should be resolved as
List<ETPTerm<?>> getValue();

I'm not an expert in Java Generics, so I need some more research.
Looks like this type resolving it'is doable, but I can't guarantee that there wouldn't be another issues after fixing that one.

because your type construction is too complex
class ETPList extends ETPTerm<List<ETPTerm<?>>>

@binarytemple
Copy link
Author

Agreed, the implementation is rather convoluted. I can work around the
issue from my side by forking and modifying the ETP library. Really the
problem here is (as with so many things) the JVM's decision to implement
type erasure. Regardless, I suspect this issue will come back to bite us -
hence my choice to spend some time debugging. Unfortunately this pattern is
somewhat common in AST generation (I myself have used similar patterns)
On 12 Jan 2015 10:39, "Bartosz Walacik" notifications@github.com wrote:

Hi, situation is quite complex here.

What we know:
Statically you are using abstract generic class:
ETPTerm

In runtime, you are using instances of
ETPList<List<ETPTerm<?>>>

The problem is, that JaVers gets confused while determinig actual type of
property
T getValue();

It should be resolved as
List<ETPTerm<?>> getValue();

I'm not an expert in Java Generics, so I need some more research.
Looks like this type resolving it'is doable, but I can't guarantee that
there wouldn't be another issues after fixing that one.

because your type construction is too complex
class ETPList extends ETPTerm<List<ETPTerm<?>>>


Reply to this email directly or view it on GitHub
#77 (comment).

@bartoszwalacik
Copy link
Member

well, type erasure has also some advantages. In this case, all types can be determined statically, so erasure is not a blocker.

For now, I'm sure that JaVers could behave better here and at least determine actual type of value().
I'm going to fix this and release new version in this week

@binarytemple
Copy link
Author

Thanks man. I'm going to see what i can do to make ETP more robust in the
meantime. B
On 12 Jan 2015 10:57, "Bartosz Walacik" notifications@github.com wrote:

well, type erasure has also some advantages. In this case, all types can
be determined statically, so erasure is not a blocker.

For now, I'm sure that JaVers could behave better here and at least
determine actual type of value().
I'm going to fix this and release new version in this week


Reply to this email directly or view it on GitHub
#77 (comment).

bartoszwalacik added a commit that referenced this issue Jan 12, 2015
first approach with JaversMember
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
refactoring: collapsing BeanProperty & FieldProperty toProperty
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
bartoszwalacik added a commit that referenced this issue Jan 12, 2015
@bartoszwalacik
Copy link
Member

I've fixed this issue, now it is waiting for CR and release 1.0.3

You can get early access to the new version, it is available as a 1.0.3-SNAPSHOT
in https://oss.sonatype.org/content/repositories/snapshots

I've pushed Javers version update to your example branch:
https://github.com/binarytemple/javers-example/commits/etp-attempt

Check it out, main problem is solved but another one arise (as I supposed).
Now you get the error:

Exception in thread "main" JaversException: GENERIC_TYPE_NOT_PARAMETRIZED JaVers runtime error - expected actual Class arguments in type 'java.util.List<com.metadave.etp.rep.ETPTerm<?>>'. JaVers is strongly-typed and needs to know actual Class of elements stored in your collections.Try at least <Object>, unbounded wildcards like <?> are not supported

JaVers is strongly-typed and we can't support types with unbounded wildcards like List<?>

List<?> is almost the same like raw List type. Raw types are usefull in Java only for backward compatibility with Java 5 and should be avoided in new code.

@binarytemple
Copy link
Author

Nice work! I had started removing all templating and generics from ETP but just removing those wildcard bounds is much easier to do. Thank you. It will be later in the week before I can test.

@bartoszwalacik
Copy link
Member

ok, so I'll close this issue as soon as javers 1.0.3 will be released to maven Central.

Give us a star if you like JaVers
https://github.com/javers/javers/stargazers

@bartoszwalacik
Copy link
Member

1.0.3 released to Central

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants