Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] call method from advice

Hi,

I tried to write a simple sample using the J2SE, but the problem with this is, that there I don't need all the things used for sending a sms on a mobile; furthermore I don't need any obfuscation and preverifying, which all is needed in my J2ME project. Maybe it helps, if you see my ant build-file, whether I am doing something wrong in the building process.

At least I wonder why, if I change only some lines in the aspect-code, so that the method "send", which is connected with a JoinPoint in the aspect, is not any longer called by the advice connected with the receive-joinpoint, then strangely everything runs well. So I have the 2 cases: 1. Program crashes with VerifyError, when the send-method (which is connected with joinpoint in the same aspect, too) is called from another advice in the same aspect directly. 2. Everything works well, if the send-method is called not directly from the aspect, but indirectly by a method which is outside the aspect. So with one level of indirection it works correct.

I don't know, but I am quiet sure, that this is an error, which occurs only with AspectJ using all the tools I am using (Obfuscation, Preverifying, J2ME). Maybe I can write a more simple program for J2ME, but as far as I tested till now, I couldn't reproduce the error in a standard-program.

Bye,
Sebastian

----- Original Message ----- From: "Wes Isberg" <wes@xxxxxxxxxxxxxx>
To: <aspectj-users@xxxxxxxxxxx>
Sent: Tuesday, February 08, 2005 7:34 PM
Subject: Re: [aspectj-users] call method from advice


when I start it in the emulator is then a
crash with the following output

Any VerifyError is a bug and should be reported as such -
unless it's caused by your bytecode obfuscator or your emulator :)

If you can write a reproducible test case (running on
1.1 VM if required), please submit it to the bug database.

For those doing obfuscation, don't forget that the AspectJ weaver
puts calls to the AspectJ runtime into woven classes,
so the obfuscator needs to handle these correctly or not
obfuscate the runtime targets.  (Generally when building,
weaving aspects should happen last, but obfuscation should
happen after that.)

Hope this helps; let us know how it works out.
Wes

------------Original Message------------
From: "Sebastian Berger" <wastel79@xxxxxx>
To: aspectj-users@xxxxxxxxxxx
Date: Tue, Feb-8-2005 9:31 AM
Subject: Re: [aspectj-users] call method from advice

I am not sure, if that helps you any further to assist me in myproblem,
but
here is the important part of my aspect:

--------------------- Aspect-Code -----------------------------
 pointcut sendMessage(sms.library.send.MessageSender sender, byte[]
messageData) : call(
   * sms.library.send.MessageSender.send(byte[])) && args(messageData)
&&
target(sender);

 pointcut receiveMessage(sms.SMSReceive receiver, byte[]
receivedMessageData, boolean newMessage) :
   call(* sms.SMSReceive.handleReceivedMessage(byte[], boolean)) &&
args(receivedMessageData, newMessage)
   && target(receiver);

 private boolean calledFromReceive = false;

 void around(sms.library.send.MessageSender sender, byte[] messageData)
:
sendMessage(sender, messageData)
 {
  if(!calledFromReceive)
  {
      // do things.... I made comments around the code in that part and
the
error still occurs
  }

  calledFromReceive=false;

  proceed(sender, messageData);
 }

 void around(sms.SMSReceive receiver, byte[] receivedMessageData,
boolean
newMessage) : receiveMessage(receiver,
       receivedMessageData, newMessage)
 {
  long sessionID = receiver.getSessionID();
   receiver.getMessageSender().setSessionID(sessionID);
   receiver.getMessageSender().send(receivedMessageData);
  proceed(receiver, receivedMessageData, newMessage);
 }
------------- End of Aspect-Code --------------------------

------------ SMSReceive ---------------------------------- (I deleted
things
which are not important)
public class SMSReceive extends AbstractScreen
{
 // MessageReceiver, über den die letzte Nachricht empfangen wurde
 private MessageReceiver lastMessageReceiver = null;


 public void handleReceivedMessage(byte[] receivedMessageData, boolean
newMessage)
 {
  if(newMessage)
  {
   smsScreen.setTitle("From: " +
lastMessageReceiver.getSenderAddress());
   smsText.setText(new String(receivedMessageData));
   display.setCurrent(smsScreen);
  }
 }


 public MessageSender getMessageSender()
 {
  System.out.println("MessageSender.getMessageSender");
  return ConnectionFactory.getInstance().getSender("50000");
 }

 public long getSessionID()
 {
  return
sms.library.NumberConverter.toLong(lastMessageReceiver.getSenderAddress());
 }
 }
------------ End: SMSReceive ----------------------------------
------------- MessageSender ------------------------------------(I
deleted
things which are not important)
public class MessageSender implements Runnable
{
 private MessageConnection senderConnection;

 private String strPort;

 private String strPhoneNumber;

 private byte[] messageData;

 /**
  * Über diese Methode wird der Thread gestartet, der das eigentliche
Senden
übernimmt.
  */
 public void send(byte[] messageData)
 {
  System.out.println("MessageSender.send");

  this.messageData = messageData;
  System.out.println("Gesendete Message-Daten: " + new
String(Hex.encode(messageData)));
        // starte neuen Thread zum Senden
        new Thread(this).start();
 }

 public void run()
 {
  System.out.println("MessageSender.run");
        try
  {
         // neue Nachricht erzeugen
         BinaryMessage binMessage =
(BinaryMessage)senderConnection.newMessage(MessageConnection.BINARY_MESSAGE);

         // Vorbereiten des Sendens der Daten in "messageData"
         String strAddress = "sms://" + strPhoneNumber + ":" + strPort;

         System.out.println("Senden einer Nachricht über Addresse: " +
strAddress);

         binMessage.setAddress(strAddress);
         binMessage.setPayloadData(messageData);

         // ... und senden der Nachricht
            senderConnection.send(binMessage);
        }
        catch (Throwable t) // Fehler fangen
  {
         System.out.println("Exception beim Senden: ");
         t.printStackTrace();
        }
 }

 /**
  * @param strPhoneNumber The strPhoneNumber to set.
  */
 public void setPhoneNumber(String strPhoneNumber)
 {
  System.out.println("MessageSender.setPhoneNumber");
  this.strPhoneNumber = strPhoneNumber;
 }

 public long getSessionID()
 {
  return sms.library.NumberConverter.toLong(this.strPhoneNumber);
 }

 public void setSessionID(long sessionID)
 {
  this.strPhoneNumber = Long.toString(sessionID);
 }
}
------------ End: MessageSender ----------------------------------

The result of my application, when I start it in the emulator is then a

crash with the following output:
     [exec] Error verifying method
org/aspectj/runtime/internal/Conversions
intV
alue(Ljava/lang/Object;)I
     [exec] Approximate bytecode offset 1: Inconsistent or missing
stackmap
at t
arget
     [exec] static Method............: e676f8 'af.a (virtual)'
     [exec] Stack Chunk.......: df4cb0
     [exec] Frame Pointer.....: df4d3c
     [exec] Current IP........: e67464 = e67430 + offset 52
     [exec] Previous Frame....: df4d08
     [exec] ALERT: java/lang/VerifyError:
org/aspectj/runtime/internal/Conversio
ns.
     [exec] Previous IP.......: e672cd (offset 45)
     [exec] Frame size........: 7 (3 arguments, 4 local variables)
     [exec] Argument[0].......: df45cc
     [exec] Argument[1].......: df5878
     [exec] Argument[2].......: df4630
     [exec] Local[3]..........: 0
     [exec] Local[4]..........: df4630
     [exec] Local[5]..........: df45cc
     [exec] Local[6]..........: df7304
     [exec] Operand[1]........: df7324
     [exec] Operand[2]........: df45cc
     [exec] Operand[3]........: df4630
     [exec] Operand[4]........: 1
     [exec] Operand[5]........: df7304
     [exec] Operand[6]........: 3
     [exec] Operand[7]........: 1

     [exec] Method............: e67300 'h.a (virtual)'
     [exec] Stack Chunk.......: df4cb0
     [exec] Frame Pointer.....: df4d08
     [exec] Current IP........: e672cd = e672a0 + offset 45
     [exec] Previous Frame....: df4ce4
     [exec] Previous IP.......: e66428 (offset 28)
     [exec] Frame size........: 3 (3 arguments, 0 local variables)
     [exec] Argument[0].......: df50ec
     [exec] Argument[1].......: 2
     [exec] Argument[2].......: df5878

     [exec] Method............: e664bc 'y.notifyIncomingMessage
(virtual)'
     [exec] Stack Chunk.......: df4cb0
     [exec] Frame Pointer.....: df4ce4
     [exec] Current IP........: e66428 = e6640c + offset 28
     [exec] Previous Frame....: df4cc4
     [exec] Previous IP.......: 10140a93 (offset 74)
     [exec] Frame size........: 2 (2 arguments, 0 local variables)
     [exec] Argument[0].......: df5878
     [exec] Argument[1].......: df57b0

     [exec] Method............: 100e27d0
'com/sun/midp/io/j2me/sms/DatagramImpl$
DatagramNotifier.run (virtual)'
     [exec] Stack Chunk.......: df4cb0
     [exec] Frame Pointer.....: df4cc4
     [exec] Current IP........: 10140a93 = 10140a49 + offset 74
     [exec] Previous Frame....: 0
     [exec] Previous IP.......: 1
     [exec] Frame size........: 3 (1 arguments, 2 local variables)
     [exec] Argument[0].......: df4f7c
     [exec] Local[1]..........: 1
     [exec] Local[2]..........: 0
----------------------- and so on and so
on ----------------------------------

When I add the following method in SMSReceiver:
 public void sendData(byte[] messageData)
 {
  getMessageSender().send(messageData);
 }
and I change the code in the around-advice connected with the
receiveMessage
pointcut to the following:
   receiver.getMessageSender().setSessionID(sessionID);
   receiver.sendData(receivedMessageData);
then the emulator doesn't crash? So this would be a fix, also very
dirty, in
my opinion, cause the SMSReceive doesn't need such a method.

What have I done wrong?

Thanks in advance, and sorry for that long email!


_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users



_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users


<project name="SMSManagement" default="dist" basedir="..">
  	<property name="project" value="SMSManagement"/>
  	
	<!-- Verzeichnisse festlegen -->
	<property name="WTK.dir"  value="C:\Programme\WTK21"/>	    
	<property name="jdk.home" value="C:\java\j2sdk" />
	<property name="ajc.home" value="C:\Programme\aspectj" />	
	<property name="ant"      value="C:\Programme\apache_ant"/>
	
	<!-- librarys, die included werden müssen -->
	<property name="MIDP.lib" value="${WTK.dir}\lib\midpapi20.jar"  />
	<property name="CLDC.lib" value="${WTK.dir}\lib\cldcapi11.jar" />
	<property name="WMA.lib" value="${WTK.dir}\lib\wma.jar"/>
	<property name="AspectJRT.lib" value="${ajc.home}/lib/aspectjrt.jar" />
	
	<!-- The following property is needed only for obufscate_proguard. -->
	<property name="proguard" value="c:\Programme\proguard\lib\proguard.jar"/>
	  
	<!-- Neuen Task definieren für AspectJ Compiler -->
	<taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
	</taskdef>
	
	<!-- Neuen Task definieren, um Größe anzupassen -->
	<taskdef name="jad" classname="JarSizeFix"/>
	
	<!-- Setzen der Pfade zum einfacheren Verwenden in Verbindung mit arglines -->
	
	<!-- AspectJ support -->
	<path id="ajc.classpath">
		<pathelement location="${ajc.home}/lib/aspectjrt.jar" />
	</path>
	
	<!-- Classpath fürs Compiling -->
	<path id="app.classpath">
	  	<pathelement location="${CLDC.lib}" />
	    <pathelement location="${MIDP.lib}" />
	    <pathelement location="${WMA.lib}"/>
	</path>
	
	<!-- Path zur Crypto-Lib fürs Compiling -->	
	<path id="app.crypt">
		<pathelement location="../lib/midp_classes.zip" />
	</path>
	
	
	<!-- Ab hier beginnen nun die verschiedenen Target -->
	
	<!-- Runs the application in the emulator. -->
	<target name="run">
		<exec executable="${WTK.dir}/bin/emulator">
	    	<arg line="-classpath build/bin/${project}.jar;${AspectJRT.lib}"/>
	      	<arg line="-Xdescriptor build/bin/${project}.jad"/>
	    </exec>
	</target>
	
	<!-- Adjusts the JAR size in the JAD. -->
	<target name="jad" depends="dist">
		<jad jar="build/bin/${project}.jar" jad="build/bin/${project}.jad"/>
	</target>
	    
	<!-- Packages the application -->
	<target name="dist" depends="preverify">
		<mkdir dir="build/bin"/>
	    <jar basedir="build/preverified"
	    	jarfile="build/bin/${project}.jar"
	        manifest="MANIFEST.MF">
	    </jar>
	    <copy file="${project}.jad"
	    	tofile="build/bin/${project}.jad"/>
	</target>
	  
	<!-- This target runs the preverifier on the class files. -->
	<target name="preverify" depends="obfuscate_proguard">
		<mkdir dir="build/preverified"/>
	    <exec executable="${WTK.dir}/bin/preverify">
	      	<arg line="-classpath ${MIDP.lib};${CLDC.lib};${ajc.home}/lib/aspectjrt.jar;${WMA.lib}"/>
	      	<arg line="-d build/preverified"/>
	      	<arg line="build/obfuscated"/>
	    </exec>
	</target>
	  
	<!-- Obufscates using ProGuard. -->
	<target name="obfuscate_proguard" depends="compile">
		<mkdir dir="build/proguard"/>
	    <jar basedir="build/classes"
	    	jarfile="build/proguard/${project}-input.jar"/>
	    <java fork="yes" classname="proguard.ProGuard"
	        classpath="${proguard}">
	    	<arg line="-libraryjars ${MIDP.lib};${CLDC.lib};${ajc.home}/lib/aspectjrt.jar;${WMA.lib}"/>
	    	<arg line="-injars build/proguard/${project}-input.jar"/>
	    	<arg line="-outjar build/proguard/${project}-output.jar"/>
	    	<arg line="-keep 'public class * extends javax.microedition.midlet.MIDlet'"/>
	    	<arg line="-defaultpackage"/>
	    	<arg line="-dontusemixedcaseclassnames"/>
	    </java>
		<mkdir dir="build/obfuscated"/>
	    <unjar src="build/proguard/${project}-output.jar"
	    	dest="build/obfuscated"/>
	</target>
	  
	<!-- Unjars the library APIs in preparation for obfuscation. -->
	<target name="copylib" depends="init">
	    <unjar src="lib/midp_classes.zip" dest="build/classes"/>
	</target>
	  
	<target name="compile" depends="init">
		<mkdir dir="build/classes"/>
	    	<iajc destdir="build/classes">
	        	<sourceroots>
		        	<pathelement location="src"/>
		    	</sourceroots>
		    	<classpath>
		        	<path refid="ajc.classpath"/>
		          	<path refid="app.classpath"/>
		          	<path refid="app.crypt"/>
		        </classpath>	
			</iajc>
	</target>
	
	<!-- Builds the JarSizeFix Ant task and installs it in the Ant lib directory. -->
	<target name="tools">
		<mkdir dir="build/tools_classes"/>
	    <javac destdir="build/tools_classes" 
	    	srcdir="build/tools"
	        target="1.1"/>
	    <jar jarfile="${ant}/lib/wd-tools.jar">
	    	<fileset dir="build/tools_classes"/>
	    </jar>
	    <delete dir="build/tools_classes"/>
	</target>
	
	<target name="init">
		<tstamp/>
	</target>
	 
	<!-- Cleans all temporary-files -->
	<target name="delete">
		<delete dir="build/classes"/>
		<delete dir="build/obfuscated"/>
		<delete dir="build/preverified"/>
		<delete dir="build/proguard"/>
		<delete dir="bin"/>		
	</target>
		
	<!-- rebuild and run -->
	<target name="rr" depends="delete, copylib, jad, run">
	</target>
	
	<!-- for fast compiling and runing -->
	<target name="fast" depends="jad, run">
	</target>

</project>

	<!-- Brauchen wir eigentlich nicht mehr... nur für das normale compiling -->
<!--	<path id="bootclasspath">
		<pathelement path="${MIDP.lib}"/>
	    <pathelement path="${CLDC.lib}"/>
	</path>
	-->
	  <!-- Compiles the source code. -->
	<!--  <target name="compile" depends="init">
	    <mkdir dir="build/classes"/>
	        <javac destdir="build/classes" srcdir="src" classpath="lib/midp_classes.zip" target="1.1">
	        	<bootclasspath refid="bootclasspath"/>
	        </javac>
	  </target>
	        	<pathelement location="C:\Programme\apache_ant\lib\aspectjrt.jar"/>
	-->

Back to the top