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

Comments

Projects
None yet
3 participants
@binarytemple

binarytemple commented Jan 7, 2015

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

This comment has been minimized.

binarytemple commented Jan 7, 2015

Forgot to mention, this is with version 1.0.1.

@pszymczyk pszymczyk self-assigned this Jan 7, 2015

@binarytemple

This comment has been minimized.

binarytemple commented Jan 7, 2015

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

This comment has been minimized.

Member

pszymczyk commented Jan 7, 2015

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

@binarytemple

This comment has been minimized.

binarytemple commented Jan 7, 2015

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

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Jan 7, 2015

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

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Jan 7, 2015

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

This comment has been minimized.

binarytemple commented Jan 7, 2015

@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

This comment has been minimized.

Member

bartoszwalacik commented Jan 8, 2015

ok, got it

@binarytemple

This comment has been minimized.

binarytemple commented Jan 8, 2015

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

This comment has been minimized.

Member

bartoszwalacik commented Jan 8, 2015

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

@binarytemple

This comment has been minimized.

binarytemple commented Jan 11, 2015

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

This comment has been minimized.

Member

bartoszwalacik commented Jan 11, 2015

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

regards

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Jan 12, 2015

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

This comment has been minimized.

binarytemple commented Jan 12, 2015

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

This comment has been minimized.

Member

bartoszwalacik commented Jan 12, 2015

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

This comment has been minimized.

binarytemple commented Jan 12, 2015

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

#77
first approach with JaversMember

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
refactoring: collapsing BeanProperty & FieldProperty toProperty

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
better Method toString

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
better Method toString

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
better exception message

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
better exception message

bartoszwalacik added a commit that referenced this issue Jan 12, 2015

#77
better exception message
@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Jan 12, 2015

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

This comment has been minimized.

binarytemple commented Jan 12, 2015

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

This comment has been minimized.

Member

bartoszwalacik commented Jan 12, 2015

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

This comment has been minimized.

Member

bartoszwalacik commented Jan 13, 2015

1.0.3 released to Central

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment