Aggregation mystery - ClassCastException on same class

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Aggregation mystery - ClassCastException on same class

hakuseki
TL;DR

We have a very interesting mystery in one of our Camel applications.

We have a route where we aggregate incoming messages.
The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.

The aggregationStrategy is from the example in documentation when wanting to aggregate a List…

LevelDB is used for persistance Repository

When flushed we process the Exchange and starts looping using a for-loop 

final List<Gateway> body=exchange.getIn().getBody(List.class);
boolean hasObject=false;
for(Gateway s:body){
final InvestmentFirm investmentFirm=s.getInvestmentFirm();
if(null!=investmentFirm){
if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
hasObject=true;
break;
}
}
}

The thing is where we get an Exception at the start of the for-loop, saying :

java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway

I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception


And if we step here it will crash.

We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…

Below is a snippet of the code 

public void configure() throws Exception {
final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();

final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
"mifir/data/shuttle/article26.dat");


//tag::route[]
from("{{shuttle.jms.incoming}}")
.unmarshal().json(JsonLibrary.Jackson, true)
.process(this::createShuttleObject)
.aggregate(constant(true), new ArrayListAggregationStrategy())
.aggregateController(defaultAggregateController)
.aggregationRepository(shuttleRepo)
.parallelProcessing(false)
.completionSize(aggregation_size)
.stopOnException()
.to("direct:investmentFirm")

.end();


from("direct:investmentFirm")
.choice()
.when(exchange -> { //<.>
final List<Gateway> body = exchange.getIn().getBody(List.class);
boolean hasObject = false;
for (Gateway s : body) {
final InvestmentFirm investmentFirm = s.getInvestmentFirm();
if (null != investmentFirm) {
if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
hasObject = true;
break;
}
}
}
log.debug("InvestmentFirms = " + hasObject);
return hasObject;
})
.end();

}
public class ArrayListAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
List<Gateway> list;


//Ignore Exception here
if (null != newExchange.getException()) {
return oldExchange;
}

//First Exchange to aggregate
if (null == oldExchange) {
list = new ArrayList<>(newBody);
newExchange.getIn().setBody(list);
return newExchange;
} else {
list = oldExchange.getIn().getBody(ArrayList.class);
list.addAll(newBody);
oldExchange.getIn().setBody(list);
return oldExchange;
}
}
}




We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”

Anyone?

Thx

M
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

Claus Ibsen-2
Hi

What Camel version are you using? And what runtime do you use, karaf, spring boot or something else?


On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander <[hidden email]> wrote:
TL;DR

We have a very interesting mystery in one of our Camel applications.

We have a route where we aggregate incoming messages.
The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.

The aggregationStrategy is from the example in documentation when wanting to aggregate a List…

LevelDB is used for persistance Repository

When flushed we process the Exchange and starts looping using a for-loop 

final List<Gateway> body=exchange.getIn().getBody(List.class);
boolean hasObject=false;
for(Gateway s:body){
final InvestmentFirm investmentFirm=s.getInvestmentFirm();
if(null!=investmentFirm){
if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
hasObject=true;
break;
}
}
}

The thing is where we get an Exception at the start of the for-loop, saying :

java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway

I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception


And if we step here it will crash.

We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…

Below is a snippet of the code 

public void configure() throws Exception {
final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();

final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
"mifir/data/shuttle/article26.dat");


//tag::route[]
from("{{shuttle.jms.incoming}}")
.unmarshal().json(JsonLibrary.Jackson, true)
.process(this::createShuttleObject)
.aggregate(constant(true), new ArrayListAggregationStrategy())
.aggregateController(defaultAggregateController)
.aggregationRepository(shuttleRepo)
.parallelProcessing(false)
.completionSize(aggregation_size)
.stopOnException()
.to("direct:investmentFirm")

.end();


from("direct:investmentFirm")
.choice()
.when(exchange -> { //<.>
final List<Gateway> body = exchange.getIn().getBody(List.class);
boolean hasObject = false;
for (Gateway s : body) {
final InvestmentFirm investmentFirm = s.getInvestmentFirm();
if (null != investmentFirm) {
if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
hasObject = true;
break;
}
}
}
log.debug("InvestmentFirms = " + hasObject);
return hasObject;
})
.end();

}
public class ArrayListAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
List<Gateway> list;


//Ignore Exception here
if (null != newExchange.getException()) {
return oldExchange;
}

//First Exchange to aggregate
if (null == oldExchange) {
list = new ArrayList<>(newBody);
newExchange.getIn().setBody(list);
return newExchange;
} else {
list = oldExchange.getIn().getBody(ArrayList.class);
list.addAll(newBody);
oldExchange.getIn().setBody(list);
return oldExchange;
}
}
}




We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”

Anyone?

Thx

M


--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

Maria Arias de Reyna Dominguez
In reply to this post by hakuseki
Hi,

A very very wild guess: could it be a problem with dependencies so you have on your classpath two versions of the same class? The JVM should choose only one of them and use it, but to me it is clear it doesn't think that the first "se.tradechannel.mifid.gateway.model.Gateway" is the same as the latter "se.tradechannel.mifid.gateway.model.Gateway". So there must be two versions of it somewhere.

On Wed, Mar 25, 2020 at 8:30 AM Mikael Andersson Wigander <[hidden email]> wrote:
TL;DR

We have a very interesting mystery in one of our Camel applications.

We have a route where we aggregate incoming messages.
The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.

The aggregationStrategy is from the example in documentation when wanting to aggregate a List…

LevelDB is used for persistance Repository

When flushed we process the Exchange and starts looping using a for-loop 

final List<Gateway> body=exchange.getIn().getBody(List.class);
boolean hasObject=false;
for(Gateway s:body){
final InvestmentFirm investmentFirm=s.getInvestmentFirm();
if(null!=investmentFirm){
if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
hasObject=true;
break;
}
}
}

The thing is where we get an Exception at the start of the for-loop, saying :

java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway

I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception


And if we step here it will crash.

We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…

Below is a snippet of the code 

public void configure() throws Exception {
final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();

final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
"mifir/data/shuttle/article26.dat");


//tag::route[]
from("{{shuttle.jms.incoming}}")
.unmarshal().json(JsonLibrary.Jackson, true)
.process(this::createShuttleObject)
.aggregate(constant(true), new ArrayListAggregationStrategy())
.aggregateController(defaultAggregateController)
.aggregationRepository(shuttleRepo)
.parallelProcessing(false)
.completionSize(aggregation_size)
.stopOnException()
.to("direct:investmentFirm")

.end();


from("direct:investmentFirm")
.choice()
.when(exchange -> { //<.>
final List<Gateway> body = exchange.getIn().getBody(List.class);
boolean hasObject = false;
for (Gateway s : body) {
final InvestmentFirm investmentFirm = s.getInvestmentFirm();
if (null != investmentFirm) {
if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
hasObject = true;
break;
}
}
}
log.debug("InvestmentFirms = " + hasObject);
return hasObject;
})
.end();

}
public class ArrayListAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
List<Gateway> list;


//Ignore Exception here
if (null != newExchange.getException()) {
return oldExchange;
}

//First Exchange to aggregate
if (null == oldExchange) {
list = new ArrayList<>(newBody);
newExchange.getIn().setBody(list);
return newExchange;
} else {
list = oldExchange.getIn().getBody(ArrayList.class);
list.addAll(newBody);
oldExchange.getIn().setBody(list);
return oldExchange;
}
}
}




We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”

Anyone?

Thx

M
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
In reply to this post by Claus Ibsen-2
Sorry

Camel 2.25.0
Spring Boot 2.1.9.RELEASE


M

> On 25 Mar 2020, at 08:47, Claus Ibsen <[hidden email]> wrote:
>
> Hi
>
> What Camel version are you using? And what runtime do you use, karaf, spring boot or something else?
>
>
> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander <[hidden email] <mailto:[hidden email]>> wrote:
> TL;DR
>
> We have a very interesting mystery in one of our Camel applications.
>
> We have a route where we aggregate incoming messages.
> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>
> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>
> LevelDB is used for persistance Repository
>
> When flushed we process the Exchange and starts looping using a for-loop
>
> final List<Gateway> body=exchange.getIn().getBody(List.class);
>         boolean hasObject=false;
>         for(Gateway s:body){
>             final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>             if(null!=investmentFirm){
>                 if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>                     hasObject=true;
>                     break;
>                 }
>             }
>         }
>
> The thing is where we get an Exception at the start of the for-loop, saying :
>
> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>
> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>
>
>
> And if we step here it will crash.
>
> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>
> Below is a snippet of the code
>
> public void configure() throws Exception {
>     final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>
>     final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>             "mifir/data/shuttle/article26.dat");
>
>
>     //tag::route[]
>     from("{{shuttle.jms.incoming}}")
>             .unmarshal().json(JsonLibrary.Jackson, true)
>             .process(this::createShuttleObject)
>             .aggregate(constant(true), new ArrayListAggregationStrategy())
>             .aggregateController(defaultAggregateController)
>             .aggregationRepository(shuttleRepo)
>             .parallelProcessing(false)
>             .completionSize(aggregation_size)
>             .stopOnException()
>             .to("direct:investmentFirm")
>
>             .end();
>
>
>     from("direct:investmentFirm")
>             .choice()
>             .when(exchange -> { //<.>
>                 final List<Gateway> body = exchange.getIn().getBody(List.class);
>                 boolean hasObject = false;
>                 for (Gateway s : body) {
>                     final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>                     if (null != investmentFirm) {
>                         if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>                             hasObject = true;
>                             break;
>                         }
>                     }
>                 }
>                 log.debug("InvestmentFirms = " + hasObject);
>                 return hasObject;
>             })
>             .end();
>
> }
> public class ArrayListAggregationStrategy implements AggregationStrategy {
>     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>         List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>         List<Gateway> list;
>
>
>         //Ignore Exception here
>         if (null != newExchange.getException()) {
>             return oldExchange;
>         }
>
>         //First Exchange to aggregate
>         if (null == oldExchange) {
>             list = new ArrayList<>(newBody);
>             newExchange.getIn().setBody(list);
>             return newExchange;
>         } else {
>             list = oldExchange.getIn().getBody(ArrayList.class);
>             list.addAll(newBody);
>             oldExchange.getIn().setBody(list);
>             return oldExchange;
>         }
>     }
> }
>
>
>
>
> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>
> Anyone?
>
> Thx
>
> M
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com <http://davsclaus.com/> @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2 <https://www.manning.com/ibsen2>
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
In reply to this post by Maria Arias de Reyna Dominguez
Well the computer never lies but when I revert to normal execution the code executes.

I have tried to use the generics as in our production mode using aggregation with List<Object> but that gives me the same error…

M

> On 25 Mar 2020, at 08:50, Maria Arias de Reyna Dominguez <[hidden email]> wrote:
>
> Hi,
>
> A very very wild guess: could it be a problem with dependencies so you have on your classpath two versions of the same class? The JVM should choose only one of them and use it, but to me it is clear it doesn't think that the first "se.tradechannel.mifid.gateway.model.Gateway" is the same as the latter "se.tradechannel.mifid.gateway.model.Gateway". So there must be two versions of it somewhere.
>
> On Wed, Mar 25, 2020 at 8:30 AM Mikael Andersson Wigander <[hidden email] <mailto:[hidden email]>> wrote:
> TL;DR
>
> We have a very interesting mystery in one of our Camel applications.
>
> We have a route where we aggregate incoming messages.
> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>
> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>
> LevelDB is used for persistance Repository
>
> When flushed we process the Exchange and starts looping using a for-loop
>
> final List<Gateway> body=exchange.getIn().getBody(List.class);
>         boolean hasObject=false;
>         for(Gateway s:body){
>             final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>             if(null!=investmentFirm){
>                 if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>                     hasObject=true;
>                     break;
>                 }
>             }
>         }
>
> The thing is where we get an Exception at the start of the for-loop, saying :
>
> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>
> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>
>
>
> And if we step here it will crash.
>
> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>
> Below is a snippet of the code
>
> public void configure() throws Exception {
>     final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>
>     final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>             "mifir/data/shuttle/article26.dat");
>
>
>     //tag::route[]
>     from("{{shuttle.jms.incoming}}")
>             .unmarshal().json(JsonLibrary.Jackson, true)
>             .process(this::createShuttleObject)
>             .aggregate(constant(true), new ArrayListAggregationStrategy())
>             .aggregateController(defaultAggregateController)
>             .aggregationRepository(shuttleRepo)
>             .parallelProcessing(false)
>             .completionSize(aggregation_size)
>             .stopOnException()
>             .to("direct:investmentFirm")
>
>             .end();
>
>
>     from("direct:investmentFirm")
>             .choice()
>             .when(exchange -> { //<.>
>                 final List<Gateway> body = exchange.getIn().getBody(List.class);
>                 boolean hasObject = false;
>                 for (Gateway s : body) {
>                     final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>                     if (null != investmentFirm) {
>                         if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>                             hasObject = true;
>                             break;
>                         }
>                     }
>                 }
>                 log.debug("InvestmentFirms = " + hasObject);
>                 return hasObject;
>             })
>             .end();
>
> }
> public class ArrayListAggregationStrategy implements AggregationStrategy {
>     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>         List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>         List<Gateway> list;
>
>
>         //Ignore Exception here
>         if (null != newExchange.getException()) {
>             return oldExchange;
>         }
>
>         //First Exchange to aggregate
>         if (null == oldExchange) {
>             list = new ArrayList<>(newBody);
>             newExchange.getIn().setBody(list);
>             return newExchange;
>         } else {
>             list = oldExchange.getIn().getBody(ArrayList.class);
>             list.addAll(newBody);
>             oldExchange.getIn().setBody(list);
>             return oldExchange;
>         }
>     }
> }
>
>
>
>
> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>
> Anyone?
>
> Thx
>
> M

Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

Zoran Regvart-2
In reply to this post by hakuseki
Hi Mikael,
ClassCastException with SameClass cannot be cast to SameClass means
that there is an object passed from one classloader and being cast to
a type loaded from another classloader.

Look at the difference between obj.getClass() and SameClass.class, I
usually check with getProtectionDomain().getCodeSource() on those
class objects.

zoran


On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
<[hidden email]> wrote:

>
> TL;DR
>
> We have a very interesting mystery in one of our Camel applications.
>
> We have a route where we aggregate incoming messages.
> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>
> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>
> LevelDB is used for persistance Repository
>
> When flushed we process the Exchange and starts looping using a for-loop
>
> final List<Gateway> body=exchange.getIn().getBody(List.class);
>         boolean hasObject=false;
>         for(Gateway s:body){
>             final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>             if(null!=investmentFirm){
>                 if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>                     hasObject=true;
>                     break;
>                 }
>             }
>         }
>
>
> The thing is where we get an Exception at the start of the for-loop, saying :
>
> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>
> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>
>
> And if we step here it will crash.
>
> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>
> Below is a snippet of the code
>
> public void configure() throws Exception {
>     final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>
>     final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>             "mifir/data/shuttle/article26.dat");
>
>
>     //tag::route[]
>     from("{{shuttle.jms.incoming}}")
>             .unmarshal().json(JsonLibrary.Jackson, true)
>             .process(this::createShuttleObject)
>             .aggregate(constant(true), new ArrayListAggregationStrategy())
>             .aggregateController(defaultAggregateController)
>             .aggregationRepository(shuttleRepo)
>             .parallelProcessing(false)
>             .completionSize(aggregation_size)
>             .stopOnException()
>             .to("direct:investmentFirm")
>
>             .end();
>
>
>     from("direct:investmentFirm")
>             .choice()
>             .when(exchange -> { //<.>
>                 final List<Gateway> body = exchange.getIn().getBody(List.class);
>                 boolean hasObject = false;
>                 for (Gateway s : body) {
>                     final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>                     if (null != investmentFirm) {
>                         if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>                             hasObject = true;
>                             break;
>                         }
>                     }
>                 }
>                 log.debug("InvestmentFirms = " + hasObject);
>                 return hasObject;
>             })
>             .end();
>
> }
>
> public class ArrayListAggregationStrategy implements AggregationStrategy {
>     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>         List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>         List<Gateway> list;
>
>
>         //Ignore Exception here
>         if (null != newExchange.getException()) {
>             return oldExchange;
>         }
>
>         //First Exchange to aggregate
>         if (null == oldExchange) {
>             list = new ArrayList<>(newBody);
>             newExchange.getIn().setBody(list);
>             return newExchange;
>         } else {
>             list = oldExchange.getIn().getBody(ArrayList.class);
>             list.addAll(newBody);
>             oldExchange.getIn().setBody(list);
>             return oldExchange;
>         }
>     }
> }
>
>
>
>
>
> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>
> Anyone?
>
> Thx
>
> M



--
Zoran Regvart
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki


> On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
> Thx

I have tried this and they are the same


************* onCompletion **************
2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Class: se.tradechannel.mifid.gateway.model.Gateway
2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9] o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange: Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation state: 1
2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation completed by: force
2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker] o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s) to recover (note some of them may already be in progress).
2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : ************* direct:investmentFirm **************
2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Class: se.tradechannel.mifid.gateway.model.Gateway
2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in ShuttleIntegration



> Hi Mikael,
> ClassCastException with SameClass cannot be cast to SameClass means
> that there is an object passed from one classloader and being cast to
> a type loaded from another classloader.
>
> Look at the difference between obj.getClass() and SameClass.class, I
> usually check with getProtectionDomain().getCodeSource() on those
> class objects.
>
> zoran
>
>
> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
> <[hidden email]> wrote:
>>
>> TL;DR
>>
>> We have a very interesting mystery in one of our Camel applications.
>>
>> We have a route where we aggregate incoming messages.
>> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
>> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>>
>> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>>
>> LevelDB is used for persistance Repository
>>
>> When flushed we process the Exchange and starts looping using a for-loop
>>
>> final List<Gateway> body=exchange.getIn().getBody(List.class);
>>        boolean hasObject=false;
>>        for(Gateway s:body){
>>            final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>>            if(null!=investmentFirm){
>>                if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>>                    hasObject=true;
>>                    break;
>>                }
>>            }
>>        }
>>
>>
>> The thing is where we get an Exception at the start of the for-loop, saying :
>>
>> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>>
>> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>>
>>
>> And if we step here it will crash.
>>
>> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>>
>> Below is a snippet of the code
>>
>> public void configure() throws Exception {
>>    final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>>
>>    final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>>            "mifir/data/shuttle/article26.dat");
>>
>>
>>    //tag::route[]
>>    from("{{shuttle.jms.incoming}}")
>>            .unmarshal().json(JsonLibrary.Jackson, true)
>>            .process(this::createShuttleObject)
>>            .aggregate(constant(true), new ArrayListAggregationStrategy())
>>            .aggregateController(defaultAggregateController)
>>            .aggregationRepository(shuttleRepo)
>>            .parallelProcessing(false)
>>            .completionSize(aggregation_size)
>>            .stopOnException()
>>            .to("direct:investmentFirm")
>>
>>            .end();
>>
>>
>>    from("direct:investmentFirm")
>>            .choice()
>>            .when(exchange -> { //<.>
>>                final List<Gateway> body = exchange.getIn().getBody(List.class);
>>                boolean hasObject = false;
>>                for (Gateway s : body) {
>>                    final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>>                    if (null != investmentFirm) {
>>                        if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>>                            hasObject = true;
>>                            break;
>>                        }
>>                    }
>>                }
>>                log.debug("InvestmentFirms = " + hasObject);
>>                return hasObject;
>>            })
>>            .end();
>>
>> }
>>
>> public class ArrayListAggregationStrategy implements AggregationStrategy {
>>    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>>        List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>>        List<Gateway> list;
>>
>>
>>        //Ignore Exception here
>>        if (null != newExchange.getException()) {
>>            return oldExchange;
>>        }
>>
>>        //First Exchange to aggregate
>>        if (null == oldExchange) {
>>            list = new ArrayList<>(newBody);
>>            newExchange.getIn().setBody(list);
>>            return newExchange;
>>        } else {
>>            list = oldExchange.getIn().getBody(ArrayList.class);
>>            list.addAll(newBody);
>>            oldExchange.getIn().setBody(list);
>>            return oldExchange;
>>        }
>>    }
>> }
>>
>>
>>
>>
>>
>> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>>
>> Anyone?
>>
>> Thx
>>
>> M
>
>
>
> --
> Zoran Regvart

Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
I implemented CompletionAwareAggregationStrategy
and in onCompletion() I checked the class but it crashes with an Ex eption in there as well…



> On 25 Mar 2020, at 09:59, Mikael Andersson Wigander <[hidden email]> wrote:
>
>
>
>> On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
>> Thx
>
> I have tried this and they are the same
>
>
> ************* onCompletion **************
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Class: se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9] o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange: Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation state: 1
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation completed by: force
> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker] o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s) to recover (note some of them may already be in progress).
> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : ************* direct:investmentFirm **************
> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Class: se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in ShuttleIntegration
>
>
>
>> Hi Mikael,
>> ClassCastException with SameClass cannot be cast to SameClass means
>> that there is an object passed from one classloader and being cast to
>> a type loaded from another classloader.
>>
>> Look at the difference between obj.getClass() and SameClass.class, I
>> usually check with getProtectionDomain().getCodeSource() on those
>> class objects.
>>
>> zoran
>>
>>
>> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
>> <[hidden email]> wrote:
>>>
>>> TL;DR
>>>
>>> We have a very interesting mystery in one of our Camel applications.
>>>
>>> We have a route where we aggregate incoming messages.
>>> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
>>> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>>>
>>> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>>>
>>> LevelDB is used for persistance Repository
>>>
>>> When flushed we process the Exchange and starts looping using a for-loop
>>>
>>> final List<Gateway> body=exchange.getIn().getBody(List.class);
>>>       boolean hasObject=false;
>>>       for(Gateway s:body){
>>>           final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>>>           if(null!=investmentFirm){
>>>               if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>>>                   hasObject=true;
>>>                   break;
>>>               }
>>>           }
>>>       }
>>>
>>>
>>> The thing is where we get an Exception at the start of the for-loop, saying :
>>>
>>> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>>>
>>> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>>>
>>>
>>> And if we step here it will crash.
>>>
>>> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>>>
>>> Below is a snippet of the code
>>>
>>> public void configure() throws Exception {
>>>   final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>>>
>>>   final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>>>           "mifir/data/shuttle/article26.dat");
>>>
>>>
>>>   //tag::route[]
>>>   from("{{shuttle.jms.incoming}}")
>>>           .unmarshal().json(JsonLibrary.Jackson, true)
>>>           .process(this::createShuttleObject)
>>>           .aggregate(constant(true), new ArrayListAggregationStrategy())
>>>           .aggregateController(defaultAggregateController)
>>>           .aggregationRepository(shuttleRepo)
>>>           .parallelProcessing(false)
>>>           .completionSize(aggregation_size)
>>>           .stopOnException()
>>>           .to("direct:investmentFirm")
>>>
>>>           .end();
>>>
>>>
>>>   from("direct:investmentFirm")
>>>           .choice()
>>>           .when(exchange -> { //<.>
>>>               final List<Gateway> body = exchange.getIn().getBody(List.class);
>>>               boolean hasObject = false;
>>>               for (Gateway s : body) {
>>>                   final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>>>                   if (null != investmentFirm) {
>>>                       if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>>>                           hasObject = true;
>>>                           break;
>>>                       }
>>>                   }
>>>               }
>>>               log.debug("InvestmentFirms = " + hasObject);
>>>               return hasObject;
>>>           })
>>>           .end();
>>>
>>> }
>>>
>>> public class ArrayListAggregationStrategy implements AggregationStrategy {
>>>   public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>>>       List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>>>       List<Gateway> list;
>>>
>>>
>>>       //Ignore Exception here
>>>       if (null != newExchange.getException()) {
>>>           return oldExchange;
>>>       }
>>>
>>>       //First Exchange to aggregate
>>>       if (null == oldExchange) {
>>>           list = new ArrayList<>(newBody);
>>>           newExchange.getIn().setBody(list);
>>>           return newExchange;
>>>       } else {
>>>           list = oldExchange.getIn().getBody(ArrayList.class);
>>>           list.addAll(newBody);
>>>           oldExchange.getIn().setBody(list);
>>>           return oldExchange;
>>>       }
>>>   }
>>> }
>>>
>>>
>>>
>>>
>>>
>>> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>>>
>>> Anyone?
>>>
>>> Thx
>>>
>>> M
>>
>>
>>
>> --
>> Zoran Regvart
>

Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

Maria Arias de Reyna Dominguez
In reply to this post by hakuseki
Hi,

So when debugging it fails and when not debugging it doesn't?

Did you compile and run the test everything inside IntellijIDEA or are you
maybe compiling outside with plain maven and running on the IDE? I had this
weird thing happening to me on eclipse several years ago and it was because
when debugging and showing the source code, it was using a different class
than when running *even when in theory they were both using the same target
folder*. Not sure why or how, couldn't really understand what happened, but
a good clean and running everything inside the IDE did the trick. Check
java versions when compiling and running (both external and internal maven,
Idea, etc...) and such.

On Wed, Mar 25, 2020 at 10:06 AM Mikael Andersson Wigander <
[hidden email]> wrote:

>
>
> > On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
> > Thx
>
> I have tried this and they are the same
>
>
> ************* onCompletion **************
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9]
> s.t.m.u.ArrayListAggregationStrategy     : Class:
> se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9]
> s.t.m.u.ArrayListAggregationStrategy     : Code source:
> file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9]
> o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange:
> Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE
>                         : Aggregation state: 1
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE
>                         : Aggregation completed by: force
> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker]
> o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s)
> to recover (note some of them may already be in progress).
> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9]
> s.t.m.gateway.routes.ShuttleIntegration  : *************
> direct:investmentFirm **************
> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9]
> s.t.m.gateway.routes.ShuttleIntegration  : Class:
> se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9]
> s.t.m.gateway.routes.ShuttleIntegration  : Code source:
> file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9]
> s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in
> ShuttleIntegration
>
>
>
> > Hi Mikael,
> > ClassCastException with SameClass cannot be cast to SameClass means
> > that there is an object passed from one classloader and being cast to
> > a type loaded from another classloader.
> >
> > Look at the difference between obj.getClass() and SameClass.class, I
> > usually check with getProtectionDomain().getCodeSource() on those
> > class objects.
> >
> > zoran
> >
> >
> > On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
> > <[hidden email]> wrote:
> >>
> >> TL;DR
> >>
> >> We have a very interesting mystery in one of our Camel applications.
> >>
> >> We have a route where we aggregate incoming messages.
> >> The messages are first unmarshalled from a JSON String to a Map<String,
> Object> and then processed thru a model ending up with a POJO of “Gateway
> objects".
> >> This POJO is then aggregated in a List<Gateway>. The POJO implements
> Serializable and has equals() and hash.
> >>
> >> The aggregationStrategy is from the example in documentation when
> wanting to aggregate a List…
> >>
> >> LevelDB is used for persistance Repository
> >>
> >> When flushed we process the Exchange and starts looping using a for-loop
> >>
> >> final List<Gateway> body=exchange.getIn().getBody(List.class);
> >>        boolean hasObject=false;
> >>        for(Gateway s:body){
> >>            final InvestmentFirm investmentFirm=s.getInvestmentFirm();
> >>            if(null!=investmentFirm){
> >>
> if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
> >>                    hasObject=true;
> >>                    break;
> >>                }
> >>            }
> >>        }
> >>
> >>
> >> The thing is where we get an Exception at the start of the for-loop,
> saying :
> >>
> >> java.lang.ClassCastException:
> se.tradechannel.mifid.gateway.model.Gateway cannot be cast to
> se.tradechannel.mifid.gateway.model.Gateway
> >>
> >> I have debugged the code and the outcome of the aggregation is a
> List<Gateway> but when starting to loop we get the exception
> >>
> >>
> >> And if we step here it will crash.
> >>
> >> We have refactored the aggregation for this route; previously we
> unmarshalled the incoming JSON string to a Map<String, Object> and
> aggregated this in a List but here we use Object as the datatype. After
> flushing we execute the same logic with the for-loop and it runs fine…
> >>
> >> Below is a snippet of the code
> >>
> >> public void configure() throws Exception {
> >>    final DefaultAggregateController defaultAggregateController = new
> DefaultAggregateController();
> >>
> >>    final LevelDBAggregationRepository shuttleRepo = new
> LevelDBAggregationRepository("shuttleArt26",
> >>            "mifir/data/shuttle/article26.dat");
> >>
> >>
> >>    //tag::route[]
> >>    from("{{shuttle.jms.incoming}}")
> >>            .unmarshal().json(JsonLibrary.Jackson, true)
> >>            .process(this::createShuttleObject)
> >>            .aggregate(constant(true), new
> ArrayListAggregationStrategy())
> >>            .aggregateController(defaultAggregateController)
> >>            .aggregationRepository(shuttleRepo)
> >>            .parallelProcessing(false)
> >>            .completionSize(aggregation_size)
> >>            .stopOnException()
> >>            .to("direct:investmentFirm")
> >>
> >>            .end();
> >>
> >>
> >>    from("direct:investmentFirm")
> >>            .choice()
> >>            .when(exchange -> { //<.>
> >>                final List<Gateway> body =
> exchange.getIn().getBody(List.class);
> >>                boolean hasObject = false;
> >>                for (Gateway s : body) {
> >>                    final InvestmentFirm investmentFirm =
> s.getInvestmentFirm();
> >>                    if (null != investmentFirm) {
> >>                        if
> (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
> >>                            hasObject = true;
> >>                            break;
> >>                        }
> >>                    }
> >>                }
> >>                log.debug("InvestmentFirms = " + hasObject);
> >>                return hasObject;
> >>            })
> >>            .end();
> >>
> >> }
> >>
> >> public class ArrayListAggregationStrategy implements
> AggregationStrategy {
> >>    public Exchange aggregate(Exchange oldExchange, Exchange
> newExchange) {
> >>        List<Gateway> newBody =
> newExchange.getIn().getBody(ArrayList.class);
> >>        List<Gateway> list;
> >>
> >>
> >>        //Ignore Exception here
> >>        if (null != newExchange.getException()) {
> >>            return oldExchange;
> >>        }
> >>
> >>        //First Exchange to aggregate
> >>        if (null == oldExchange) {
> >>            list = new ArrayList<>(newBody);
> >>            newExchange.getIn().setBody(list);
> >>            return newExchange;
> >>        } else {
> >>            list = oldExchange.getIn().getBody(ArrayList.class);
> >>            list.addAll(newBody);
> >>            oldExchange.getIn().setBody(list);
> >>            return oldExchange;
> >>        }
> >>    }
> >> }
> >>
> >>
> >>
> >>
> >>
> >> We really can’t see what the heck is going on, it seems OK everything
> but "the computer says No!”
> >>
> >> Anyone?
> >>
> >> Thx
> >>
> >> M
> >
> >
> >
> > --
> > Zoran Regvart
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

Zoran Regvart-2
In reply to this post by hakuseki
Hi Mikael,
in the output you provided you're printing the name of the class, my
remark was about the fact that in Java you can have the same named
class loaded by two classloaders result in a ClassCastException. I
also provided a way to check for that.

zoran

On Wed, Mar 25, 2020 at 9:59 AM Mikael Andersson Wigander
<[hidden email]> wrote:

>
>
>
> > On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
> > Thx
>
> I have tried this and they are the same
>
>
> ************* onCompletion **************
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Class: se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9] o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange: Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation state: 1
> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation completed by: force
> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker] o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s) to recover (note some of them may already be in progress).
> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : ************* direct:investmentFirm **************
> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Class: se.tradechannel.mifid.gateway.model.Gateway
> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in ShuttleIntegration
>
>
>
> > Hi Mikael,
> > ClassCastException with SameClass cannot be cast to SameClass means
> > that there is an object passed from one classloader and being cast to
> > a type loaded from another classloader.
> >
> > Look at the difference between obj.getClass() and SameClass.class, I
> > usually check with getProtectionDomain().getCodeSource() on those
> > class objects.
> >
> > zoran
> >
> >
> > On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
> > <[hidden email]> wrote:
> >>
> >> TL;DR
> >>
> >> We have a very interesting mystery in one of our Camel applications.
> >>
> >> We have a route where we aggregate incoming messages.
> >> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
> >> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
> >>
> >> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
> >>
> >> LevelDB is used for persistance Repository
> >>
> >> When flushed we process the Exchange and starts looping using a for-loop
> >>
> >> final List<Gateway> body=exchange.getIn().getBody(List.class);
> >>        boolean hasObject=false;
> >>        for(Gateway s:body){
> >>            final InvestmentFirm investmentFirm=s.getInvestmentFirm();
> >>            if(null!=investmentFirm){
> >>                if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
> >>                    hasObject=true;
> >>                    break;
> >>                }
> >>            }
> >>        }
> >>
> >>
> >> The thing is where we get an Exception at the start of the for-loop, saying :
> >>
> >> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
> >>
> >> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
> >>
> >>
> >> And if we step here it will crash.
> >>
> >> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
> >>
> >> Below is a snippet of the code
> >>
> >> public void configure() throws Exception {
> >>    final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
> >>
> >>    final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
> >>            "mifir/data/shuttle/article26.dat");
> >>
> >>
> >>    //tag::route[]
> >>    from("{{shuttle.jms.incoming}}")
> >>            .unmarshal().json(JsonLibrary.Jackson, true)
> >>            .process(this::createShuttleObject)
> >>            .aggregate(constant(true), new ArrayListAggregationStrategy())
> >>            .aggregateController(defaultAggregateController)
> >>            .aggregationRepository(shuttleRepo)
> >>            .parallelProcessing(false)
> >>            .completionSize(aggregation_size)
> >>            .stopOnException()
> >>            .to("direct:investmentFirm")
> >>
> >>            .end();
> >>
> >>
> >>    from("direct:investmentFirm")
> >>            .choice()
> >>            .when(exchange -> { //<.>
> >>                final List<Gateway> body = exchange.getIn().getBody(List.class);
> >>                boolean hasObject = false;
> >>                for (Gateway s : body) {
> >>                    final InvestmentFirm investmentFirm = s.getInvestmentFirm();
> >>                    if (null != investmentFirm) {
> >>                        if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
> >>                            hasObject = true;
> >>                            break;
> >>                        }
> >>                    }
> >>                }
> >>                log.debug("InvestmentFirms = " + hasObject);
> >>                return hasObject;
> >>            })
> >>            .end();
> >>
> >> }
> >>
> >> public class ArrayListAggregationStrategy implements AggregationStrategy {
> >>    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
> >>        List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
> >>        List<Gateway> list;
> >>
> >>
> >>        //Ignore Exception here
> >>        if (null != newExchange.getException()) {
> >>            return oldExchange;
> >>        }
> >>
> >>        //First Exchange to aggregate
> >>        if (null == oldExchange) {
> >>            list = new ArrayList<>(newBody);
> >>            newExchange.getIn().setBody(list);
> >>            return newExchange;
> >>        } else {
> >>            list = oldExchange.getIn().getBody(ArrayList.class);
> >>            list.addAll(newBody);
> >>            oldExchange.getIn().setBody(list);
> >>            return oldExchange;
> >>        }
> >>    }
> >> }
> >>
> >>
> >>
> >>
> >>
> >> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
> >>
> >> Anyone?
> >>
> >> Thx
> >>
> >> M
> >
> >
> >
> > --
> > Zoran Regvart
>


--
Zoran Regvart
Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
In reply to this post by Maria Arias de Reyna Dominguez
Running inside IDE and also from a maven run, same issue

M

> On 25 Mar 2020, at 10:12, Maria Arias de Reyna Dominguez <[hidden email]> wrote:
>
> Hi,
>
> So when debugging it fails and when not debugging it doesn't?
>
> Did you compile and run the test everything inside IntellijIDEA or are you
> maybe compiling outside with plain maven and running on the IDE? I had this
> weird thing happening to me on eclipse several years ago and it was because
> when debugging and showing the source code, it was using a different class
> than when running *even when in theory they were both using the same target
> folder*. Not sure why or how, couldn't really understand what happened, but
> a good clean and running everything inside the IDE did the trick. Check
> java versions when compiling and running (both external and internal maven,
> Idea, etc...) and such.
>
> On Wed, Mar 25, 2020 at 10:06 AM Mikael Andersson Wigander <
> [hidden email]> wrote:
>
>>
>>
>>> On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
>>> Thx
>>
>> I have tried this and they are the same
>>
>>
>> ************* onCompletion **************
>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9]
>> s.t.m.u.ArrayListAggregationStrategy     : Class:
>> se.tradechannel.mifid.gateway.model.Gateway
>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9]
>> s.t.m.u.ArrayListAggregationStrategy     : Code source:
>> file:/Users/mgr/IdeaProjects/mifid/target/classes/
>> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9]
>> o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange:
>> Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE
>>                        : Aggregation state: 1
>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE
>>                        : Aggregation completed by: force
>> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker]
>> o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s)
>> to recover (note some of them may already be in progress).
>> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9]
>> s.t.m.gateway.routes.ShuttleIntegration  : *************
>> direct:investmentFirm **************
>> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9]
>> s.t.m.gateway.routes.ShuttleIntegration  : Class:
>> se.tradechannel.mifid.gateway.model.Gateway
>> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9]
>> s.t.m.gateway.routes.ShuttleIntegration  : Code source:
>> file:/Users/mgr/IdeaProjects/mifid/target/classes/
>> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9]
>> s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in
>> ShuttleIntegration
>>
>>
>>
>>> Hi Mikael,
>>> ClassCastException with SameClass cannot be cast to SameClass means
>>> that there is an object passed from one classloader and being cast to
>>> a type loaded from another classloader.
>>>
>>> Look at the difference between obj.getClass() and SameClass.class, I
>>> usually check with getProtectionDomain().getCodeSource() on those
>>> class objects.
>>>
>>> zoran
>>>
>>>
>>> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
>>> <[hidden email]> wrote:
>>>>
>>>> TL;DR
>>>>
>>>> We have a very interesting mystery in one of our Camel applications.
>>>>
>>>> We have a route where we aggregate incoming messages.
>>>> The messages are first unmarshalled from a JSON String to a Map<String,
>> Object> and then processed thru a model ending up with a POJO of “Gateway
>> objects".
>>>> This POJO is then aggregated in a List<Gateway>. The POJO implements
>> Serializable and has equals() and hash.
>>>>
>>>> The aggregationStrategy is from the example in documentation when
>> wanting to aggregate a List…
>>>>
>>>> LevelDB is used for persistance Repository
>>>>
>>>> When flushed we process the Exchange and starts looping using a for-loop
>>>>
>>>> final List<Gateway> body=exchange.getIn().getBody(List.class);
>>>>       boolean hasObject=false;
>>>>       for(Gateway s:body){
>>>>           final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>>>>           if(null!=investmentFirm){
>>>>
>> if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>>>>                   hasObject=true;
>>>>                   break;
>>>>               }
>>>>           }
>>>>       }
>>>>
>>>>
>>>> The thing is where we get an Exception at the start of the for-loop,
>> saying :
>>>>
>>>> java.lang.ClassCastException:
>> se.tradechannel.mifid.gateway.model.Gateway cannot be cast to
>> se.tradechannel.mifid.gateway.model.Gateway
>>>>
>>>> I have debugged the code and the outcome of the aggregation is a
>> List<Gateway> but when starting to loop we get the exception
>>>>
>>>>
>>>> And if we step here it will crash.
>>>>
>>>> We have refactored the aggregation for this route; previously we
>> unmarshalled the incoming JSON string to a Map<String, Object> and
>> aggregated this in a List but here we use Object as the datatype. After
>> flushing we execute the same logic with the for-loop and it runs fine…
>>>>
>>>> Below is a snippet of the code
>>>>
>>>> public void configure() throws Exception {
>>>>   final DefaultAggregateController defaultAggregateController = new
>> DefaultAggregateController();
>>>>
>>>>   final LevelDBAggregationRepository shuttleRepo = new
>> LevelDBAggregationRepository("shuttleArt26",
>>>>           "mifir/data/shuttle/article26.dat");
>>>>
>>>>
>>>>   //tag::route[]
>>>>   from("{{shuttle.jms.incoming}}")
>>>>           .unmarshal().json(JsonLibrary.Jackson, true)
>>>>           .process(this::createShuttleObject)
>>>>           .aggregate(constant(true), new
>> ArrayListAggregationStrategy())
>>>>           .aggregateController(defaultAggregateController)
>>>>           .aggregationRepository(shuttleRepo)
>>>>           .parallelProcessing(false)
>>>>           .completionSize(aggregation_size)
>>>>           .stopOnException()
>>>>           .to("direct:investmentFirm")
>>>>
>>>>           .end();
>>>>
>>>>
>>>>   from("direct:investmentFirm")
>>>>           .choice()
>>>>           .when(exchange -> { //<.>
>>>>               final List<Gateway> body =
>> exchange.getIn().getBody(List.class);
>>>>               boolean hasObject = false;
>>>>               for (Gateway s : body) {
>>>>                   final InvestmentFirm investmentFirm =
>> s.getInvestmentFirm();
>>>>                   if (null != investmentFirm) {
>>>>                       if
>> (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>>>>                           hasObject = true;
>>>>                           break;
>>>>                       }
>>>>                   }
>>>>               }
>>>>               log.debug("InvestmentFirms = " + hasObject);
>>>>               return hasObject;
>>>>           })
>>>>           .end();
>>>>
>>>> }
>>>>
>>>> public class ArrayListAggregationStrategy implements
>> AggregationStrategy {
>>>>   public Exchange aggregate(Exchange oldExchange, Exchange
>> newExchange) {
>>>>       List<Gateway> newBody =
>> newExchange.getIn().getBody(ArrayList.class);
>>>>       List<Gateway> list;
>>>>
>>>>
>>>>       //Ignore Exception here
>>>>       if (null != newExchange.getException()) {
>>>>           return oldExchange;
>>>>       }
>>>>
>>>>       //First Exchange to aggregate
>>>>       if (null == oldExchange) {
>>>>           list = new ArrayList<>(newBody);
>>>>           newExchange.getIn().setBody(list);
>>>>           return newExchange;
>>>>       } else {
>>>>           list = oldExchange.getIn().getBody(ArrayList.class);
>>>>           list.addAll(newBody);
>>>>           oldExchange.getIn().setBody(list);
>>>>           return oldExchange;
>>>>       }
>>>>   }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> We really can’t see what the heck is going on, it seems OK everything
>> but "the computer says No!”
>>>>
>>>> Anyone?
>>>>
>>>> Thx
>>>>
>>>> M
>>>
>>>
>>>
>>> --
>>> Zoran Regvart
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
In reply to this post by Zoran Regvart-2
Hi

Yes, I tried that but maybe I implement4d it wrong:

final List<Gateway> body = exchange.getIn().getBody(List.class);
final Class<?> aClass = body.get(0).getClass();
final CodeSource codeSource = aClass.getProtectionDomain().getCodeSource();
log.info("************* onCompletion **************");
log.info("Class: " +aClass.getName());
log.info("Code source: " + codeSource.getLocation());
M



> On 25 Mar 2020, at 10:12, Zoran Regvart <[hidden email]> wrote:
>
> Hi Mikael,
> in the output you provided you're printing the name of the class, my
> remark was about the fact that in Java you can have the same named
> class loaded by two classloaders result in a ClassCastException. I
> also provided a way to check for that.
>
> zoran
>
> On Wed, Mar 25, 2020 at 9:59 AM Mikael Andersson Wigander
> <[hidden email]> wrote:
>>
>>
>>
>>> On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email]> wrote:
>>> Thx
>>
>> I have tried this and they are the same
>>
>>
>> ************* onCompletion **************
>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Class: se.tradechannel.mifid.gateway.model.Gateway
>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
>> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9] o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange: Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation state: 1
>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation completed by: force
>> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker] o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s) to recover (note some of them may already be in progress).
>> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : ************* direct:investmentFirm **************
>> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Class: se.tradechannel.mifid.gateway.model.Gateway
>> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
>> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in ShuttleIntegration
>>
>>
>>
>>> Hi Mikael,
>>> ClassCastException with SameClass cannot be cast to SameClass means
>>> that there is an object passed from one classloader and being cast to
>>> a type loaded from another classloader.
>>>
>>> Look at the difference between obj.getClass() and SameClass.class, I
>>> usually check with getProtectionDomain().getCodeSource() on those
>>> class objects.
>>>
>>> zoran
>>>
>>>
>>> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
>>> <[hidden email]> wrote:
>>>>
>>>> TL;DR
>>>>
>>>> We have a very interesting mystery in one of our Camel applications.
>>>>
>>>> We have a route where we aggregate incoming messages.
>>>> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
>>>> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>>>>
>>>> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>>>>
>>>> LevelDB is used for persistance Repository
>>>>
>>>> When flushed we process the Exchange and starts looping using a for-loop
>>>>
>>>> final List<Gateway> body=exchange.getIn().getBody(List.class);
>>>>       boolean hasObject=false;
>>>>       for(Gateway s:body){
>>>>           final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>>>>           if(null!=investmentFirm){
>>>>               if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>>>>                   hasObject=true;
>>>>                   break;
>>>>               }
>>>>           }
>>>>       }
>>>>
>>>>
>>>> The thing is where we get an Exception at the start of the for-loop, saying :
>>>>
>>>> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>>>>
>>>> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>>>>
>>>>
>>>> And if we step here it will crash.
>>>>
>>>> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>>>>
>>>> Below is a snippet of the code
>>>>
>>>> public void configure() throws Exception {
>>>>   final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>>>>
>>>>   final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>>>>           "mifir/data/shuttle/article26.dat");
>>>>
>>>>
>>>>   //tag::route[]
>>>>   from("{{shuttle.jms.incoming}}")
>>>>           .unmarshal().json(JsonLibrary.Jackson, true)
>>>>           .process(this::createShuttleObject)
>>>>           .aggregate(constant(true), new ArrayListAggregationStrategy())
>>>>           .aggregateController(defaultAggregateController)
>>>>           .aggregationRepository(shuttleRepo)
>>>>           .parallelProcessing(false)
>>>>           .completionSize(aggregation_size)
>>>>           .stopOnException()
>>>>           .to("direct:investmentFirm")
>>>>
>>>>           .end();
>>>>
>>>>
>>>>   from("direct:investmentFirm")
>>>>           .choice()
>>>>           .when(exchange -> { //<.>
>>>>               final List<Gateway> body = exchange.getIn().getBody(List.class);
>>>>               boolean hasObject = false;
>>>>               for (Gateway s : body) {
>>>>                   final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>>>>                   if (null != investmentFirm) {
>>>>                       if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>>>>                           hasObject = true;
>>>>                           break;
>>>>                       }
>>>>                   }
>>>>               }
>>>>               log.debug("InvestmentFirms = " + hasObject);
>>>>               return hasObject;
>>>>           })
>>>>           .end();
>>>>
>>>> }
>>>>
>>>> public class ArrayListAggregationStrategy implements AggregationStrategy {
>>>>   public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>>>>       List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>>>>       List<Gateway> list;
>>>>
>>>>
>>>>       //Ignore Exception here
>>>>       if (null != newExchange.getException()) {
>>>>           return oldExchange;
>>>>       }
>>>>
>>>>       //First Exchange to aggregate
>>>>       if (null == oldExchange) {
>>>>           list = new ArrayList<>(newBody);
>>>>           newExchange.getIn().setBody(list);
>>>>           return newExchange;
>>>>       } else {
>>>>           list = oldExchange.getIn().getBody(ArrayList.class);
>>>>           list.addAll(newBody);
>>>>           oldExchange.getIn().setBody(list);
>>>>           return oldExchange;
>>>>       }
>>>>   }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>>>>
>>>> Anyone?
>>>>
>>>> Thx
>>>>
>>>> M
>>>
>>>
>>>
>>> --
>>> Zoran Regvart
>>
>
>
> --
> Zoran Regvart

Reply | Threaded
Open this post in threaded view
|

Re: Aggregation mystery - ClassCastException on same class

hakuseki
Hi, all

I think I found the problem.

When running with a LevelDB repository it fails but switching to a JDBC Repository it works.

So somewhere deep in LevelDB then…

M

> On 25 Mar 2020, at 10:16, Mikael Andersson Wigander <[hidden email]> wrote:
>
> Hi
>
> Yes, I tried that but maybe I implement4d it wrong:
>
> final List<Gateway> body = exchange.getIn().getBody(List.class);
> final Class<?> aClass = body.get(0).getClass();
> final CodeSource codeSource = aClass.getProtectionDomain().getCodeSource();
> log.info("************* onCompletion **************");
> log.info("Class: " +aClass.getName());
> log.info("Code source: " + codeSource.getLocation());
> M
>
>
>
>> On 25 Mar 2020, at 10:12, Zoran Regvart <[hidden email] <mailto:[hidden email]>> wrote:
>>
>> Hi Mikael,
>> in the output you provided you're printing the name of the class, my
>> remark was about the fact that in Java you can have the same named
>> class loaded by two classloaders result in a ClassCastException. I
>> also provided a way to check for that.
>>
>> zoran
>>
>> On Wed, Mar 25, 2020 at 9:59 AM Mikael Andersson Wigander
>> <[hidden email] <mailto:[hidden email]>> wrote:
>>>
>>>
>>>
>>>> On 25 Mar 2020, at 09:28, Zoran Regvart <[hidden email] <mailto:[hidden email]>> wrote:
>>>> Thx
>>>
>>> I have tried this and they are the same
>>>
>>>
>>> ************* onCompletion **************
>>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Class: se.tradechannel.mifid.gateway.model.Gateway
>>> 2020-03-25 09:57:16.747  INFO 77480 --- [nio-8080-exec-9] s.t.m.u.ArrayListAggregationStrategy     : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
>>> 2020-03-25 09:57:16.748 DEBUG 77480 --- [nio-8080-exec-9] o.a.c.p.aggregate.AggregateProcessor     : Processing aggregated exchange: Exchange[ID-MAW-MacBook-Space-local-1585126611320-0-2]
>>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation state: 1
>>> 2020-03-25 09:57:16.751  INFO 77480 --- [nio-8080-exec-9] SHUTTLE                                  : Aggregation completed by: force
>>> 2020-03-25 09:57:20.709 DEBUG 77480 --- [eRecoverChecker] o.a.c.c.l.LevelDBAggregationRepository   : Scanned and found 1 exchange(s) to recover (note some of them may already be in progress).
>>> 2020-03-25 09:57:24.563  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : ************* direct:investmentFirm **************
>>> 2020-03-25 09:57:25.090  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Class: se.tradechannel.mifid.gateway.model.Gateway
>>> 2020-03-25 09:57:25.795  INFO 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Code source: file:/Users/mgr/IdeaProjects/mifid/target/classes/
>>> 2020-03-25 09:57:42.410 ERROR 77480 --- [nio-8080-exec-9] s.t.m.gateway.routes.ShuttleIntegration  : Error occurred in ShuttleIntegration
>>>
>>>
>>>
>>>> Hi Mikael,
>>>> ClassCastException with SameClass cannot be cast to SameClass means
>>>> that there is an object passed from one classloader and being cast to
>>>> a type loaded from another classloader.
>>>>
>>>> Look at the difference between obj.getClass() and SameClass.class, I
>>>> usually check with getProtectionDomain().getCodeSource() on those
>>>> class objects.
>>>>
>>>> zoran
>>>>
>>>>
>>>> On Wed, Mar 25, 2020 at 8:23 AM Mikael Andersson Wigander
>>>> <[hidden email] <mailto:[hidden email]>> wrote:
>>>>>
>>>>> TL;DR
>>>>>
>>>>> We have a very interesting mystery in one of our Camel applications.
>>>>>
>>>>> We have a route where we aggregate incoming messages.
>>>>> The messages are first unmarshalled from a JSON String to a Map<String, Object> and then processed thru a model ending up with a POJO of “Gateway objects".
>>>>> This POJO is then aggregated in a List<Gateway>. The POJO implements Serializable and has equals() and hash.
>>>>>
>>>>> The aggregationStrategy is from the example in documentation when wanting to aggregate a List…
>>>>>
>>>>> LevelDB is used for persistance Repository
>>>>>
>>>>> When flushed we process the Exchange and starts looping using a for-loop
>>>>>
>>>>> final List<Gateway> body=exchange.getIn().getBody(List.class);
>>>>>       boolean hasObject=false;
>>>>>       for(Gateway s:body){
>>>>>           final InvestmentFirm investmentFirm=s.getInvestmentFirm();
>>>>>           if(null!=investmentFirm){
>>>>>               if(StringUtils.isNoneBlank(investmentFirm.getExternalId())){
>>>>>                   hasObject=true;
>>>>>                   break;
>>>>>               }
>>>>>           }
>>>>>       }
>>>>>
>>>>>
>>>>> The thing is where we get an Exception at the start of the for-loop, saying :
>>>>>
>>>>> java.lang.ClassCastException: se.tradechannel.mifid.gateway.model.Gateway cannot be cast to se.tradechannel.mifid.gateway.model.Gateway
>>>>>
>>>>> I have debugged the code and the outcome of the aggregation is a List<Gateway> but when starting to loop we get the exception
>>>>>
>>>>>
>>>>> And if we step here it will crash.
>>>>>
>>>>> We have refactored the aggregation for this route; previously we unmarshalled the incoming JSON string to a Map<String, Object> and aggregated this in a List but here we use Object as the datatype. After flushing we execute the same logic with the for-loop and it runs fine…
>>>>>
>>>>> Below is a snippet of the code
>>>>>
>>>>> public void configure() throws Exception {
>>>>>   final DefaultAggregateController defaultAggregateController = new DefaultAggregateController();
>>>>>
>>>>>   final LevelDBAggregationRepository shuttleRepo = new LevelDBAggregationRepository("shuttleArt26",
>>>>>           "mifir/data/shuttle/article26.dat");
>>>>>
>>>>>
>>>>>   //tag::route[]
>>>>>   from("{{shuttle.jms.incoming}}")
>>>>>           .unmarshal().json(JsonLibrary.Jackson, true)
>>>>>           .process(this::createShuttleObject)
>>>>>           .aggregate(constant(true), new ArrayListAggregationStrategy())
>>>>>           .aggregateController(defaultAggregateController)
>>>>>           .aggregationRepository(shuttleRepo)
>>>>>           .parallelProcessing(false)
>>>>>           .completionSize(aggregation_size)
>>>>>           .stopOnException()
>>>>>           .to("direct:investmentFirm")
>>>>>
>>>>>           .end();
>>>>>
>>>>>
>>>>>   from("direct:investmentFirm")
>>>>>           .choice()
>>>>>           .when(exchange -> { //<.>
>>>>>               final List<Gateway> body = exchange.getIn().getBody(List.class);
>>>>>               boolean hasObject = false;
>>>>>               for (Gateway s : body) {
>>>>>                   final InvestmentFirm investmentFirm = s.getInvestmentFirm();
>>>>>                   if (null != investmentFirm) {
>>>>>                       if (StringUtils.isNoneBlank(investmentFirm.getExternalId())) {
>>>>>                           hasObject = true;
>>>>>                           break;
>>>>>                       }
>>>>>                   }
>>>>>               }
>>>>>               log.debug("InvestmentFirms = " + hasObject);
>>>>>               return hasObject;
>>>>>           })
>>>>>           .end();
>>>>>
>>>>> }
>>>>>
>>>>> public class ArrayListAggregationStrategy implements AggregationStrategy {
>>>>>   public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
>>>>>       List<Gateway> newBody = newExchange.getIn().getBody(ArrayList.class);
>>>>>       List<Gateway> list;
>>>>>
>>>>>
>>>>>       //Ignore Exception here
>>>>>       if (null != newExchange.getException()) {
>>>>>           return oldExchange;
>>>>>       }
>>>>>
>>>>>       //First Exchange to aggregate
>>>>>       if (null == oldExchange) {
>>>>>           list = new ArrayList<>(newBody);
>>>>>           newExchange.getIn().setBody(list);
>>>>>           return newExchange;
>>>>>       } else {
>>>>>           list = oldExchange.getIn().getBody(ArrayList.class);
>>>>>           list.addAll(newBody);
>>>>>           oldExchange.getIn().setBody(list);
>>>>>           return oldExchange;
>>>>>       }
>>>>>   }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> We really can’t see what the heck is going on, it seems OK everything but "the computer says No!”
>>>>>
>>>>> Anyone?
>>>>>
>>>>> Thx
>>>>>
>>>>> M
>>>>
>>>>
>>>>
>>>> --
>>>> Zoran Regvart
>>>
>>
>>
>> --
>> Zoran Regvart
>