| RE: [aspectj-users] instrumenting JAXB-generated classes |
|
Well, I am back after stumbling across
more problems with instrumenting JAXB classes, which seems to have something to
do with annotations. I have an aspect com.nextpage.tester.aspects.TParameterizer
which I use to instrument JAXB-generated classes. Everything works fine until I
add “perthis(execution (TXmlTestSuite.new(..)))” to the aspect
declaration. For some reason it causes JAXB to choke when analyzing
TXmlTestSuite class and throw an exception shown at the bottom of this message. TXmlTestSuite class is just a POJO class
generated by JAXB. It doesn’t have any declared constructor and has the
following declaration: @XmlAccessorType(AccessType.FIELD) @XmlType(name = "TXmlTestSuite",
propOrder = { "include" }) public class TXmlTestSuite { .. } Based on this class declaration and
exceptions shown below it seems that aspects weaved in TXmlTestSuite class by
AspectJ interfere with the class annotations. Is this an AspectJ or JAXB bug or am I
doing something wrong? Is there a work-around solution that would allow me to
create a separate instance of TParameterizer aspect for each instance of
TXmlTestSuite without breaking anything else? Thanks. com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:
1 counts of IllegalAnnotationExceptions Property
ajc$com_nextpage_tester_aspects_TParameterizer$perObjectField is present but
not specified in @XmlType.propOrder this
problem is related to the following location: at
private transient com.nextpage.tester.aspects.TParameterizer
com.nextpage.tester.domain.xml.actions.TXmlTestSuite.ajc$com_nextpage_tester_aspects_TParameterizer$perObjectField at
com.nextpage.tester.domain.xml.actions.TXmlTestSuite at
public com.nextpage.tester.domain.xml.actions.TXmlTestSuite
com.nextpage.tester.domain.xml.actions.ObjectFactory.createTXmlTestSuite() at
com.nextpage.tester.domain.xml.actions.ObjectFactory at
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66) at
com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:330) at
com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:198) at
com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76) at
com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55) at
com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:124) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at
java.lang.reflect.Method.invoke(Method.java:585) at
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:132) at
javax.xml.bind.ContextFinder.find(ContextFinder.java:286) at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:358) at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:323) at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:244) at
com.nextpage.tester.util.TXmlUnmarshaller.unmarshal(TXmlUnmarshaller.java:109) at
com.nextpage.tester.application.actions.TTestSuite.unmarshalTestSuite(TTestSuite.java:232) at
com.nextpage.tester.application.actions.TTestSuite.<init>(TTestSuite.java:52) at
com.nextpage.tester.application.TMain.runTests(TMain.java:140) at
com.nextpage.tester.application.TMain$TMainRunner.main(TMain.java:366) From:
aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Alec Lebedev I think you are right and field values do get
set through reflection API in JAXB-generated classes. Could you or anybody else
provide more information on how to capture reflective calls that set field
values. Thanks, Alec From:
aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Adrian Colyer I haven't looked at the
JAXB generated code, but it's likely that the field values are set reflectively
in this case. There is no set join point when using the reflection APIs to set
field values (but there is a call join point for the call to the reflection API
method). On 31/05/06, Alec
Lebedev <alec.lebedev@xxxxxxxxxxxx>
wrote: Hi, I
am using JAXB to generate Java classes based on the given XML schema. I then
try to weave aspects in the generated classes, but I can't seem to capture when
fields of JAXB-generated classes get set at runtime. Below
are the two advices which I am trying to weave in the TXmlEntity JAXB-generated
class. Note that the first advice fires up just fine and prints out correct
XmlIds. However, the second aspect never gets fired. I don't understand how
xmlId field in TXmlEntity class gets set if the second (setter) advice never
fires up and the first (getter) one prints out correct xmlId values? after
(TXmlEntity var) : get (* TXmlEntity.*) && this(var) &&
!cflowbelow(adviceexecution()) {
logger.error(" } after
(TXmlEntity var) : set (* TXmlEntity.*) && this(var) &&
!cflowbelow(adviceexecution()) {
logger.error("Setting: " + var.getXmlId()); } TXmlEntity
is just a POJO class shown below. // // This
file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference
Implementation, v2.0-hudson-3037-ea3 //
See <a href="" href="http://java.sun.com/xml/jaxb" target="_blank">http://java.sun.com/xml/jaxb">
http://java.sun.com/xml/jaxb</a> //
Any modifications to this file will be lost upon recompilation of the source
schema. //
Generated on: 2006.05.31 at 10:19:36 AM MDT // package
com.nextpage.tester.domain.xml.entities; import
javax.xml.bind.annotation.AccessType; import
javax.xml.bind.annotation.XmlAccessorType; import
javax.xml.bind.annotation.XmlAttribute; import
javax.xml.bind.annotation.XmlElement; import
javax.xml.bind.annotation.XmlID; import
javax.xml.bind.annotation.XmlType; import
javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import
javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import
com.nextpage.tester.domain.xml.entities.Adapter1; import
com.nextpage.tester.domain.xml.entities.TXmlEntity; /** *
<p>Java class for TXmlEntity complex type. *
*
<p>The following schema fragment specifies the expected content contained
within this class. *
*
<pre> *
<complexType name="TXmlEntity"> *
<complexContent> *
<restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> *
<sequence> *
<element name="dbId" type="{http://www.w3.org/2001/XMLSchema}anySimpleType"
minOccurs="0"/> *
</sequence> *
<attribute name="client-entity" type="{http://www.w3.org/2001/XMLSchema}boolean"
/> *
<attribute name="server-entity" type="{http://www.w3.org/2001/XMLSchema}boolean"
/> *
<attribute name="xmlId" use="required" type="{http://www.w3.org/2001/XMLSchema}ID"
/> *
</restriction> *
</complexContent> *
</complexType> *
</pre> *
*
*/ @XmlAccessorType(AccessType.FIELD) @XmlType(name
= "TXmlEntity", propOrder = {
"dbId" }) public
class TXmlEntity {
@XmlElement(namespace = "http://nextpage.com/tester/domain", type =
String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
protected Object dbId;
@XmlAttribute(name = "client-entity")
protected Boolean clientEntity;
@XmlAttribute(name = "server-entity")
protected Boolean serverEntity;
@XmlAttribute(required = true)
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlID
protected String xmlId;
/**
* Gets the value of the dbId property.
*
* @return
* possible object is
* {@link String }
*
*/
public Object getDbId() {
return dbId;
}
/**
* Sets the value of the dbId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setDbId(Object value) {
this.dbId = value;
}
/**
* Gets the value of the clientEntity property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isClientEntity() {
return clientEntity;
}
/**
* Sets the value of the clientEntity property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setClientEntity(Boolean value) {
this.clientEntity = value;
}
/**
* Gets the value of the serverEntity property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isServerEntity() {
return serverEntity;
}
/**
* Sets the value of the serverEntity property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setServerEntity(Boolean value) {
this.serverEntity = value;
}
/**
* Gets the value of the xmlId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getXmlId() {
return xmlId;
}
/**
* Sets the value of the xmlId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setXmlId(String value) {
this.xmlId = value;
} }
|