Using Aspects in a java application - when javac/ajc? - aop

I think about using AspectJ in an existing project.
I have several pure Java Eclipse projects and I like to create an AOP project.
I'm not quite sure about when ajc is needed and when optional. We use Ant (with javac) as our main build and I would like to avoid changing the build.
Is the following possible:
I have a AspectJ enabled Eclipse and create my aspect project. I create a jar from this and include this jar with the aspectj jar in the normal eclipse workspace with the other projects.
The build includes my aspect jar and the aspectj jar as dependency jars with javac.
Is this enough for working with the aspects ?
Or do every project of the application needs to be compiled with ajc ?
The main goal is to keep the current structure of Eclipse setup and build environment as as much as possible as it is now.
Or is this only possible with the annotation style ? (if so can someone link me some information about the weaver and how to do this at runtime ?)
Thank you

If you want to weave your aspect into your codebase, you must use AJC. If you only use javac, even with the annotation, your code won't be weaved by your aspects.
That being said, you don't have to add a lot to your ant build.
something like that should do the job:
<path id="ajclasspath">
<path refid="classpath"/>
<pathelement location="${scm.home}/ant_libs/aspectjrt.jar"/>
</path>
<iajc inpath="${classes.dir}" destDir="${classes.dir}" fork="true" maxmem="${aspectj.maxmem}">
<argfiles refid="aspectj.argfiles.path"/>
<classpath refid="ajclasspath"/>
</iajc>
In fact, you just build like normal and you add a step with the iajc taking your output dir of the javac compile as the inpath and you put the result in the same directory.
You can also take a jar as input to iajc and produce a jar with all your stuff weaved inside.
Edit: Or you can use runtime weaving, if your app is a web application, it is not too bad. If not, i do not recommand runtime weaving, since each time you will start your app, it might be a lot longer to start. I don't have a lot of experience with runtime weaving, but you can check it out. I know you need a aop.xml to define your aspects.
Regards

Related

AspectJ project as a jar to another project

I have 2 projects.
Project A - This is an aspectJ project. For example: It prints the method name and time taken, in console after execution of each method.
Project B - It is a sample web project.
I want to add Project A as a Jar to Project B. So whenever I run Project B, it should display what are the method names and time taken.
Since I am new to AspectJ , could someone explain how to do this. Please explain with some sample projects.
Thanks in advance.
You have several options:
Use A as an aspect library when compiling B with the AspectJ compiler Ajc. This can be done from command line, from IDE with the right project configuration or, most conveniently, via AspectJ Maven plugin.
Use A as an aspect library and B as a weave dependency in a post-processing step with Ajc. As before, this can be done from command line, from IDE with the right project configuration or, most conveniently, via AspectJ Maven plugin.
Use load-time weaving (LTW) via -javaagent:/path/to/aspectjweaver.jar command-line switch when starting your Java application containing B and put A on the classpath as an aspect library.
For more information please use your favourite web search engine, specifying search terms like "aspectj ltw", "aspectj maven plugin", "aspectj ajc" or similar.
P.S.: Why should anyone provide one or multiple full sample projects if you are too lazy to provide a single line of code?

How to integrate Proguard obfuscation in my JavaFX's IntelliJ artifact?

I'm developing a JavaFX application using IntelliJ IDEA as the IDE.
So far, everything runs smoothly, I have all my external libs configured and my JavaFX artifact being correctly created.
Now I would like to integrate obfuscation (using Proguard) when the artifact is created.
IntelliJ have a 'Pre-processing' and 'Post-processing' option in artifact's properties where I can define an Ant task to be runned.
But I have no idea how to create that task and tell the compiler my obfuscation options.
Thank you very much in advance for any clues,
Best regards
There are 3 basic ways you do it:
Create a normal proguard.cfg file, and reference it from ant
Put your proguard settings directly inside ant using XML notation
Put your proguard settings directly inside ant using the proguard.cfg format
Here's a basic example of using Proguard with Ant with the 3rd approach:
http://www.reviewmylife.co.uk/blog/2007/10/20/proguard-eclipse-ant-buildxml/
The important thing to remember about Proguard is that everything you want to obfuscate has to be inside a JAR file, and you'll need to explicitly tell it not to obfuscate certain things (like your program entry point, things you access via reflection, etc).
JavaFX creates a file used as an entry point you want to prevent obfuscating:
-keepclasseswithmembers public class com.javafx.main.Main {
public *; public static *;
}
Make sure to include Java/JavaFX libs
-libraryjars "${java.home}/lib/rt.jar"
-libraryjars "${java.home}/lib/ant-javafx.jar"
-libraryjars "${java.home}/lib/jfxrt.jar"
If you're using FXML files, you'll want to make sure your FXML files are renamed similarly to their respective controller file:
-adaptresourcefilecontents **.fxml
Anything annotated with #FXML is accessed through reflection, so don't obfuscate them:
-keepclassmembernames class * {
#javafx.fxml.FXML *;
}
The Proguard website has a lot of information, but it can be difficult to grok.
Honestly, there are plenty of examples on the web that show you how to do this. Just google javafx proguard, and you'll probably find some good complete examples.
Edit: as far as how IntelliJ passes information to Ant.. I don't know. There are probably some variables it passes in that you reference like a normal Ant propertly. I'm sure JetBrains website has info on that on their website if you can't find it on the net.
If it was me, I'd just create an ant script to compile my application without obfuscation, then add in proguard once you've got that squared away.
Just some complementing information, regarding running an Ant task in idea's 'post-processing'.
Make sure you have a 'default' target. Else the task wont execute. Example of build.xml:
<?xml version="1.0"?>
<project name="ant_task" default="obfuscate" basedir=".">
<target name="obfuscate">
<taskdef resource="proguard/ant/task.properties"
classpath="/opt/proguard5.2.1/lib/proguard.jar" />
<proguard configuration="proguard.cfg"/>
</target>
</project>

How to add the target jar as a test resource of the same project?

I'm developing a Solr plugin and using the Solr test-framework I place a test SOLR_HOME dir under test/resources with /conf/ and /lib . Now the framework inistantiates a SolrCore and loads my plugin from /lib. Not an issue to output the jar of the plugin to /lib, but the issue is that the plugin is not yet available since it still needs to past the test (chicken and the egg).
How do you recommend solving this? I see those options:
Create another project for the tests with a dependency on the plugin, and in it run the tests. Simple enough, but how do I ensure that everytime the plugin is built also the tests of this other project is built? The point of the automated tests at every build is to having a new plugin jar which breaks the tests.
In dp4j pom.xml I build the project on 2 phases, in the 1st I <include> only the annotation processors while in the other I compile the tests which rely on the annotation processors compiled in the eariler phase.
I'm in favor of 2 since copy-pasting the configuration doesn't seem a bad option, and makes it seem less complicated than it probably is. I don't remember if I had asked about it here - what do you recommend? Any other case studies /working code to look at?
there's a 3rd. most probably best solution ~ do nothing!
I was under the impression that the Solr Testframework need to load my plugin from /lib but apparently it doesn't need to, it can load it from test-classes, all on its own!

Looking for a simple example to fire "make" from Maven2

This is a transitional solution.
I don't want to write my own plugin.
I have too many small, scattered makefiles to convert to pom.xml all at once.
I'm trying to move to Maven2 as a skunkworks project and gradually migrage new + changing code to pom.xml files.
The arch-independent C/C++ solutions are not needed - plus the Makefile run multiple scripts to generate code before compilation.
Any pointers to extending "mvn deploy" to handle "make deploy" would be great.
Thanks
AJ
You should check Codehaus' related CBUILDS project. It may help you with downloading dependencies, unpacking, patching, and invoking make.
I'm a bit confused as to why you're moving towards maven with C projects, but if I were you, I'd look at gmaven-plugin to execute an inline groovy script to invoke what you need. Then, if you want to create a plugin later, it should be easy to migrate to one.

ant/maven integration

I have a project that is built and managed by Maven. I have a second project that has an ant build. I'd like to reference the maven project from the ant project and pull in all of the required dependencies. Can anyone suggest a way to do this?
thanks,
Jeff
The maven-ant-tasks work quite well for this sort of thing.
You can use Ivy:
Ivy can therefore be used to bring the
dependency management feature of maven
to Ant build files, for those of you
who already use Ant and who do not
want to setup a maven project.
Apache Ivy is an Ant library that can handle Maven-style repositories.
Here's a page which describes the differences between them and how to integrate the two.
There are a set of ant tasks for Mercury that allow you to perform dependency management tasks, specify configuration (e.g. server credentials), modify/alter the ant path and write to the repository. See this blog for details.
There are also Maven tasks for ant, though they are not as fully featured. Maven is moving towards Mercury (particularly for Maven3) so it makes sense to use the Mercury tasks.
The following configuration reads the dependencies from the specified pom and populates the specified variable with the resultant path:
<path id="my.compile.path">
<deps>
<dependency name="groupId:artifactId:1.0::pom"
pom="${basedir}/artifactId-1.0.pom"/>
</deps>
</path>
You can also use the Mercury tasks to deploy to a Maven repository using an Ant build file:
<repo id="myRepository"
url="http://localhost:8081/nexus/content/groups/public">
<auth name="myUser" pass="myPassword"/>
</repo>
<write repoid="myRepository"
name="my.group.id:my-artifact-id:1.0"
file="${basedir}/target/my-artifact-id.jar"/>