ProxyGen and abstract classes

178 views
Skip to first unread message

Carlos Rijo

unread,
Feb 6, 2017, 5:55:55 PM2/6/17
to vert.x
Hello, I have an interface annotated with @ProxyGen, some methods have an abstract class as argument and I'm getting this error when generating the source files.

The UML is pretty simple, the abstract class is the class Animal, and only one class extends it, which is the Bird class.

What am I doing wrong?

Here is the stack trace:

SEVERE: Could not generate model for getAnimal(java.lang.String,java.lang.String,io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>>): type io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>> is not legal for use for a parameter in proxy
io.vertx.codegen.GenException: type io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>> is not legal for use for a parameter in proxy
 at io.vertx.codegen.ProxyModel.checkParamType(ProxyModel.java:91)
 at io.vertx.codegen.ClassModel.getParams(ClassModel.java:866)
 at io.vertx.codegen.ClassModel.addMethod(ClassModel.java:715)
 at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
 at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419)
 at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
 at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
 at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
 at java.util.Iterator.forEachRemaining(Iterator.java:116)
 at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
 at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
 at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
 at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
 at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
 at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
 at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
 at io.vertx.codegen.ClassModel.traverseElem(ClassModel.java:573)
 at io.vertx.codegen.ClassModel.process(ClassModel.java:481)
 at io.vertx.codegen.CodeGen.getProxyModel(CodeGen.java:218)
 at io.vertx.codegen.CodeGen.lambda$null$17(CodeGen.java:141)
 at io.vertx.codegen.CodeGen$ModelEntry.getValue(CodeGen.java:106)
 at io.vertx.codegen.CodeGen$ModelEntry.getValue(CodeGen.java:88)
 at io.vertx.codegen.CodeGenProcessor.lambda$process$1(CodeGenProcessor.java:152)
 at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
 at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1683)
 at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
 at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
 at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
 at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
 at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
 at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
 at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
 at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
 at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
 at io.vertx.codegen.CodeGenProcessor.process(CodeGenProcessor.java:150)
 at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
 at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
 at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
 at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
 at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
 at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
 at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
 at com.sun.tools.javac.main.Main.compile(Main.java:523)
 at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
 at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
 at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:125)
 at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:169)
 at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:825)
 at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
 at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
 at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
 at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
 at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
 at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
 at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
 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:497)
 at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
 at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
 at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
 at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/Rubito/IdeaProjects/thesis_mock/src/main/java/thesis/service/FooDatabaseService.java:[35,10] Could not generate model for getAnimal(java.lang.String,java.lang.String,io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>>): type io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>> is not legal for use for a parameter in proxy
[INFO] 1 error[INFO] -------------------------------------------------------------

Thanks in advance, cheers~ 

Carlos Rijo

unread,
Feb 6, 2017, 9:33:30 PM2/6/17
to vert.x
I've searched more and got an answer.

According to a github issue, Julien states "Data object params needs to be a plain class because it needs to be reconstructed from Json format ...". This is for @DataObject but I think @ProxyGen uses the same mechanism so the "problem" remains.
Julien suggests the following:

"We could work around this by having a static method fromJson returning an instance of that object that would be invoked by the generator, delegating the responsibility of creating the right instance to this method. This method could either use some hard coded mechanism or something else." 


Hope this helps, cheers ;)

Julien Viet

unread,
Feb 7, 2017, 5:53:38 PM2/7/17
to ve...@googlegroups.com
yes this is correct, thanks for replying to yourself :-)

-- 
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/ec6cf005-8a2d-4c3d-8381-192f8c27db2e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Carlos Rijo

unread,
Feb 7, 2017, 7:26:20 PM2/7/17
to vert.x
You're welcome ;)

Not sure if it is good practice because normally you'd follow the abstract factory pattern I think.

On Tuesday, February 7, 2017 at 10:53:38 PM UTC, Julien Viet wrote:
yes this is correct, thanks for replying to yourself :-)
On Feb 7, 2017, at 3:33 AM, Carlos Rijo <c.b...@campus.fct.unl.pt> wrote:
I've searched more and got an answer.
According to a github issue, Julien states "Data object params needs to be a plain class because it needs to be reconstructed from Json format ...". This is for @DataObject but I think @ProxyGen uses the same mechanism so the "problem" remains.
Julien suggests the following:
Link here 
Hope this helps, cheers ;)
On Monday, February 6, 2017 at 10:55:55 PM UTC, Carlos Rijo wrote:
Hello, I have an interface annotated with @ProxyGen, some methods have an abstract class as argument and I'm getting this error when generating the source files.
The UML is pretty simple, the abstract class is the class Animal, and only one class extends it, which is the Bird class.
What am I doing wrong?
Here is the stack trace:
"We could work around this by having a static method fromJson returning an instance of that object that would be invoked by the generator, delegating the responsibility of creating the right instance to this method. This method could either use some hard coded mechanism or something else." 
SEVERE: Could not generate model for getAnimal(java.lang.String,java.lang.String,io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>>): type io.vertx.core.Handler<io.vertx.core.AsyncResult<thesis.entity.Animal>> is not legal for use for a parameter in proxy

Julien Viet

unread,
Feb 8, 2017, 2:37:03 AM2/8/17
to ve...@googlegroups.com
it’s not really about the factory, but decoupling the creation of an object from the “new” statement.

any other solution is welcome, or perhaps it should just remain forbidden.



Carlos Rijo

unread,
Feb 9, 2017, 6:25:09 AM2/9/17
to vert.x
I think it should remain forbidden. Since we are exposing a service that communicates with a database we want to return a model, as in, something concrete, so even tho the abstraction helps it doesn't actually models the reality/whats in the DB.
Not sure if this way of thinking is correct...

Another solution could be to return a JsonObject that would later be used (by the controller) to create the model, that is what I'm doing right now and it works as expected.

François Delalleau

unread,
Feb 10, 2017, 12:41:48 AM2/10/17
to vert.x
I think it should not be forbidden. DataObject returned by service proxies are not always database object's, and sometimes abstract object or interface can be usefull.

Just an example, I work on project where different services use common interfaces as representation. Proxygen template was rewrited to use a ServiceLoader to find the write implmentation in each service. For example, the "Stock" interface is implemented as a warehouse in the supply chain service, and as an employee in the timesheet service. Contract is the same, but implementations are really different.

I think that documentation must be clearer, and precise that it's dev responsability to rewrite (or not use) generation if proxy (or pther dataobjects) have interfaces or abstract class as param/field. And maybe exclude them from the default generation.

Another thing that can be good, following the same idea, is to prevent usage of a specific codegen on an api, to avoid duplicate generation if you rewrite one of them...

Reply all
Reply to author
Forward
0 new messages