Am 12.12.14 16:48 schrieb "andrewcelerity" unter
<and...@celerityglobal.com>:

>Java 8 made a changes to generics that is currently not allowing camel to
>start up, and if it did start up would be in a bad state.  Bridge methods
>now get a copy of the annotations placed on the real method.  This is bad
>when combined with Camel annotations.  For example:
>
>interface Something<T extends SomeType> {
>  void doSomethingWith(T it);
>}
>
>class Foo implements Something<RealType> {
>
>  @Consume(uri = "...")
>  @Override
>  public void doSomethingWith(RealType it) {
>     .....
>  }
>
>}
>
>The class the compiler makes actually looks like this because of type
>erasure:
>class Foo implements Something<RealType> {
>
>  @Consume(uri = "...")
>  @Override
>  public void doSomethingWith(RealType it) {
>     .....
>  }
>
>  @Consume(uri = "...")
>  @Override
>  public void doSomethingWith(SomeType it) {
>     .....
>  }
>
>}
>
>
>This is a breaking change as far as Camel is concered for 2 reasons:
>  1. BeanInfo.isValidMethod does not allow for bridge methods
>  2. There are now 2 methods listening to the same endpoint
>
>Is this a bug that should be reported?  Any ideas on a workaround?  I'm
>about to downgrade to java 7.

Hi

Which Camel version do you use? Java 8 support is given from Camel 2.14.x
onwards.

That said, I'm not sure if there's really any difference by the generated
byte code as you claim no matter if Java 7 or 8 is in use. With the
following source:

import org.apache.camel.Consume;

interface Something<T extends Number> {
  void doSomethingWith(T it);
}

class Foo implements Something<Long> {

  @Consume(uri = "direct:start")
  @Override
  public void doSomethingWith(Long it) {
  }
}

Now decompiling the class file for the source above, no matter if Java 7
or 8 compiler is in use, you get the *same* decompiled source out of the
byte code, which is:

class Foo
implements Something
{

Foo()
{
}

public void doSomethingWith(Long long1)
{
}

public volatile void doSomethingWith(Number number)
{
  doSomethingWith((Long)number);
}
}


Note that all the Java generics sugar inside the byte code is gone. So
unter the hut the generated byte code is exactly the same. And when you
would do

myFoo.doSomethingWith(3L);

inside your Java source code, the compiler does call the second method
above (the one with Number as the argument type). And the cast to type
Long inside the byte code above is guaranteed to succeed *if* you don't
have any unchecked/type safety warnings while compiling the source
(assuming no @SuppressWarnings is in use).

Babak


>
>
>
>--
>View this message in context:
>http://camel.465427.n5.nabble.com/Changes-in-Java-8-generics-breaking-Came
>l-tp5760638.html
>Sent from the Camel - Users mailing list archive at Nabble.com.


Reply via email to