AspectJ: Difference between revisions

From air
Jump to navigation Jump to search
Line 9: Line 9:
Installer [[Maven]]
Installer [[Maven]]


Créer un projet Maven
Tester l'exemple suivant

<pre>
<pre>
mkdir -p aj/src/main/java
git clone https://github.com/jbellmann/aspectj-examples.git
cd aspectj-examples/
mvn clean install
</pre>
</pre>


Changer aspectj-examples/application/src/main/java/de/jbellmann/application/Main.java
Créer le fichier aj/src/main/java/fr/imag/air/aj/SimpleThreads.java
par https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html
<pre>
<pre>
// From https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html
package fr.imag.air.aj;
package fr.imag.air.aj;


Line 105: Line 104:
</pre>
</pre>


Créer le fichier aj/src/main/java/fr/imag/air/aj/DurationAspect.aj
Ajouter les aspects suivants dans aspectj-examples/aspects/src/main/java/de/jbellmann/aspects



<pre>
<pre>
Line 114: Line 112:
private long startTime;
private long startTime;
private long count = 0;
private long count = 0;
private static long globalDuration=0;
private static long globalCount = 0;
before() : execution(public void *.run()){
before() : execution(public void *.run()){
start=System.nanoTime();
startTime=System.nanoTime();
count++;
count++;
globalCount++;
}
}


after() : execution(public void *.run()){
after() : execution(public void *.run()){
long endTime=System.nanoTime();
long endTime=System.nanoTime();
System.out.println("Call #" + count + ": Duration=" + (endTime-startTime)/1000000);
long delta = endTime-startTime;
globalDuration +=delta;
System.out.println("Call #" + count + ": Duration=" + delta/1000000);
}

before() : execution(public void SimpleThreads.main(..)){
System.out.println("START STATISTICS ");
}

after() : execution(public void SimpleThreads.main(..)){
System.out.println("END STATISTICS ");
System.out.println("CallNumber: " + globalCount + " : AvgDuration=" + (globalDuration/(globalCount*1000000)));
}
}
}
}



</pre>
</pre>


Créer le fichier aj/pom.xml

<pre>
<pre>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>


<groupId>fr.imag.air.aj</groupId>
...
<artifactId>examples</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>AspectJ examples</name>

<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<aspectj.version>1.8.6</aspectj.version>
<exec-maven-plugin.version>1.4.0</exec-maven-plugin.version>
</properties>


<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<outxml>true</outxml>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<complianceLevel>${maven.compiler.target}</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<version>${exec-maven-plugin.version}</version>
<executions>
<executions>
<execution>
<execution>
Line 144: Line 217:
</executions>
</executions>
<configuration>
<configuration>
<mainClass>fr.imag.air.aj.SimpleThreads</mainClass>
<mainClass>${project.groupId}.SimpleThreads</mainClass>
</configuration>
</configuration>
</plugin>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</project>




</plugins>
</pre>
</pre>


=Exercice=

Transformer l'aspect précédent pour créer un quota d'utilisation du temps passé dans la méthode ''void run()''.
Transformer l'aspect précédent pour créer un quota d'utilisation du temps passé dans la méthode ''void run()''.
Un paramêtre est un débit maximun par appel (cumulé depuis le démarrage du programme). Tester s'il y a dépassement en début d'appel (''before()'') et si besoin mettre en sommeil la thread la durée nécessaire (''Thread.sleep(millisec)'').
Un paramêtre est un débit maximun par appel (cumulé depuis le démarrage du programme). Tester s'il y a dépassement en début d'appel (''before()'') et si besoin mettre en sommeil la thread la durée nécessaire (''Thread.sleep(millisec)'').

QuotaAspect.aj
<pre>

TODO

</pre>

Revision as of 12:42, 15 March 2016



Avec Maven

Installer Maven

Créer un projet Maven

mkdir -p aj/src/main/java

Créer le fichier aj/src/main/java/fr/imag/air/aj/SimpleThreads.java

// From https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html
package fr.imag.air.aj;

public class SimpleThreads {

    // Display a message, preceded by
    // the name of the current thread
    static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }

    private static class MessageLoop
        implements Runnable {
        public void run() {
            String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
            };
            try {
                for (int i = 0;
                     i < importantInfo.length;
                     i++) {
                    // Pause for 4 seconds
                    Thread.sleep(4000);
                    // Print a message
                    threadMessage(importantInfo[i]);
                }
            } catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    public static void main(String args[])
        throws InterruptedException {

        // Delay, in milliseconds before
        // we interrupt MessageLoop
        // thread (default one hour).
        long patience = 1000 * 60 * 60;

        // If command line argument
        // present, gives patience
        // in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }
        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        // loop until MessageLoop
        // thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            // Wait maximum of 1 second
            // for MessageLoop thread
            // to finish.
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience)
                  && t.isAlive()) {
                threadMessage("Tired of waiting!");
                t.interrupt();
                // Shouldn't be long now
                // -- wait indefinitely
                t.join();
            }
        }
        threadMessage("Finally!");
    }
}

Créer le fichier aj/src/main/java/fr/imag/air/aj/DurationAspect.aj

package fr.imag.air.aj;

public aspect DurationAspect {
    private long startTime;
    private long count = 0;
    private static long globalDuration=0;
    private static long globalCount = 0;
    
    before() : execution(public void *.run()){
        startTime=System.nanoTime();
        count++;
        globalCount++;
    }

    after() : execution(public void *.run()){
        long endTime=System.nanoTime();
        long delta = endTime-startTime;
        globalDuration +=delta;
        System.out.println("Call #" + count + ": Duration=" + delta/1000000);
    }

    before() : execution(public void SimpleThreads.main(..)){
    	System.out.println("START STATISTICS ");
    }

    after() : execution(public void SimpleThreads.main(..)){
    	System.out.println("END STATISTICS ");
        System.out.println("CallNumber: " + globalCount + " : AvgDuration=" + (globalDuration/(globalCount*1000000)));
    }
}


Créer le fichier aj/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>fr.imag.air.aj</groupId>
	<artifactId>examples</artifactId>
	<version>0.1.0-SNAPSHOT</version>
	<name>AspectJ examples</name>

    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <aspectj.version>1.8.6</aspectj.version>
        <exec-maven-plugin.version>1.4.0</exec-maven-plugin.version>
    </properties>


	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>aspectj-maven-plugin</artifactId>
					<version>1.7</version>
				</plugin>
			</plugins>
		</pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.2</version>
				<configuration>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>aspectj-maven-plugin</artifactId>
				<configuration>
					<outxml>true</outxml>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
					<complianceLevel>${maven.compiler.target}</complianceLevel>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
							<goal>test-compile</goal>
						</goals>
					</execution>
				</executions>
				<dependencies>
					<dependency>
						<groupId>org.aspectj</groupId>
						<artifactId>aspectjtools</artifactId>
						<version>${aspectj.version}</version>
					</dependency>
				</dependencies>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<version>${exec-maven-plugin.version}</version>
				<executions>
					<execution>
						<goals>
							<goal>java</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<mainClass>${project.groupId}.SimpleThreads</mainClass>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${aspectj.version}</version>
		</dependency>
	</dependencies>
	
</project>


Exercice

Transformer l'aspect précédent pour créer un quota d'utilisation du temps passé dans la méthode void run(). Un paramêtre est un débit maximun par appel (cumulé depuis le démarrage du programme). Tester s'il y a dépassement en début d'appel (before()) et si besoin mettre en sommeil la thread la durée nécessaire (Thread.sleep(millisec)).