Community
Participate
Working Groups
I posted this to the pde-dev mailing list and was asked to raise a bug, so here it is: --- I am trying to work on the pde export facilities of AJDT (aspectj tool support for Eclipse). Currently, AJDT provides custom wizards for exporting plugins, features, and products, as well as headless build support. The problem is that these wizards are essentially a copy of pde export wizards. And this is difficult to maintain for each new release. For the Helios release, I am considering a different approach for aspectj aware pde export and pde builds. Essentially, the requirement is that the pde build happens as normal, except that the javac call should be replaced with a call to iajc (with a few extra options). I've been playing around a bit and I am able to get this mostly working through a customBuildCallBack.xml script and adding some ant commands to the @dot.post.compile task. In this task, I first delete the class files created by the javac call, and then I call the iajc task. There are some problems, however: 1. This feels hacky. The code is compiled twice and the results of the first compile is deleted. 2. The javac call will likely have some compile errors (expected because javac cannot compile the aspects). These errors will be logged and can be confusing to users. 3. Source bundles will not include the *.aj files unless there is something added to the customBuildCallBack.xml script (I think...I haven't actually tried to fix this yet). Note that I am having this problem with AspectJ-aware bundles, but I know this is also a problem for Groovy-aware bundles. And I expect that scala-aware modules and any other Java-like language will have the same problem. Any ideas on a more graceful solution to the porblem? I see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=105631 but I don't know how relevant that is.
Responding to my initial comment, Andrew Neifer suggested that I look into overriding the ${build.compiler} property in the build.properties file of the plugin. However, when I tried this, it does not work. I think the problem has to do with the following line in ModelBuildScriptGenerator.java (line 927 in 3.6M5): script.printProperty(PROPERTY_BUILD_COMPILER, JDT_COMPILER_ADAPTER); PROPERTY_BUILD_COMPILER should be set according to what is in the build.properties file, rather than being fixed to JDT_COMPILER_ADAPTER. I think it would be a fairly simple fix to get this property from build.properties rather than having it fixed. I can submit a patch. But, this is only part of the solution. I need a way to pass in arbitrary compiler and vm arguments. I also need a way to specify which file extensions are included in the source bundle.
I didn't meant to imply this works today, we will need to make changes to read the property from the bundle's build.properties. We will actually need to set it directly as an attribute on the javac task. Currently, build.compiler needs to be set by the top level build configuration. You might be able to set it in your Ant -> Runtime -> Properties preferences to try things with export.
And presumably, the same would need to happen for the ${compilerArg} property. This would allow the passing of an arbitrary command line. As for source bundles, I think it would be sufficient to add a new property supported by build.properties (such as javaLikeFileExtensions), which contains a comma separated list of all recognized file extensions of Java-like files in the project (eg- *.java, *.groovy, *.aj, etc). If omitted, this defaults to *.java. The file extensions in javaLikeFileExtensions would have to be used in the generated build.xml whenever an ant fileset specifies **/*.java. Again, this does not seem to be a big change to ModelBuildScriptGenerator. I have not been able to try this out, but my guess is that this would be sufficient for what I need. If you think this is a reasonable suggestion, I can submit a patch.
(In reply to comment #3) > As for source bundles, I think it would be sufficient to add a new property > supported by build.properties (such as javaLikeFileExtensions), which contains > a comma separated list of all recognized file extensions of Java-like files in > the project (eg- *.java, *.groovy, *.aj, etc). If omitted, this defaults to > *.java. The file extensions in javaLikeFileExtensions would have to be used in > the generated build.xml whenever an ant fileset specifies **/*.java. > > Again, this does not seem to be a big change to ModelBuildScriptGenerator. I > have not been able to try this out, but my guess is that this would be > sufficient for what I need. If you think this is a reasonable suggestion, I > can submit a patch. This also would affect what gets copied into the binary bundles, currently, everything under the source folders that aren't *.java or package.html will be copied (this is generally *.properties files). But if your sources are some other extension then they get copied into the binary bundle when you didn't intend them to. How about "sourceFileExtensions" instead of "javaLike".
(In reply to comment #4) > This also would affect what gets copied into the binary bundles, currently, > everything under the source folders that aren't *.java or package.html will be > copied (this is generally *.properties files). But if your sources are some > other extension then they get copied into the binary bundle when you didn't > intend them to. Yes. I meant to say that, but neglected to mention it. > How about "sourceFileExtensions" instead of "javaLike". Sure.
Created attachment 160373 [details] First attempt at patch Here's a first go at the patch to allow javac to be overridden. I allow for 3 new properties to be specified in build.properties: build.compiler : the compiler adapter sourceFileExtensions : list of file extensions of recognized source files compilerArg : an argument line passed to the compiler If any of these are missing, then they default to the current values (ie- org.eclipse.jdt.core.JDTCompilerAdapter, *.java, and ""). If this looks good to you, I can provide some tests as well.
Created attachment 160383 [details] new patch The file extension part was good. For "build.compiler" and "compilerArg", both of those properties are likely to have been previously declared by the headless build environment for all bundles. Ant properties don't change, so setting them here like this won't work. Instead we basically generate the bundle's build.properties settings directly into the xml. For the compiler adapter, we write the value directly into a <javac/> compiler attribute. Similarly the value for the compilerArg is generated directly as a <compilerarg/> element in the xml. Also, we are already passing some arguments to the compiler: the original ${compilerArg}, a "-log", and a "@" argument file. It is likely that the global settings for compileArgs won't necessarily work in a different compiler adapter, so I left that being specific to the global ${build.compiler}. for the log and the arg file, I added two more properties that the bundle can set if its custom compiler adapter will understand those options. With this new patch, the properties are: sourceFileExtensions : as before compilerArg : as before compilerAdapter : a custom compiler adapter to use compilerAdapter.useLog : set to "true" to receive the -log argument compilerAdapter.useArgFile : set to "true" to receive the '@' argument file I haven't tested any of this. Would there be any need for a bundle to use more than one compiler adapter (ie, some regular java + some aspect or groovy)? We could do compilerAdapter.<library>, and allow setting a different adapter on each library. You could then have a bundle something like: my.bundle_1.0.0.jar: - META-INF/MANIFEST.MF: Bundle-Classpath: java/, groovy/ Eclipse-BundleShape: jar - java/**/*.class - groovy/**/*.class (assuming groovy generates class files) build.properties src.java = src_java/ src.groovy = src_groovy/ compilerAdapter.groovy = myGroovyAdapter We can't separate on source folder, only library.
Thanks for the quick response. (In reply to comment #7) > compilerAdapter.useLog : set to "true" to receive the -log argument > compilerAdapter.useArgFile : set to "true" to receive the '@' argument file Any reason not to set these to true by default? The compilers that I work with are basically JDT-derived and so should be able to accept all arguments that the jdt compiler accepts. And I'd bet that compiler adapters that would not accept these arguments would just ignore them. (This is a minor point though.) > Would there be any need for a bundle to use more than one compiler adapter (ie, > some regular java + some aspect or groovy)? We could do > compilerAdapter.<library>, and allow setting a different adapter on each > library. I can't see why this would be useful. All of these kinds of projects that I know of use a single builder/compiler that compile all kinds of source files (this is important to ensure integration with JDT).
Created attachment 160446 [details] Test cases Here are a few tests for the new functionality. The tests just ensure that the proper parts of the build script are created when these new properties are set.
And I have successfully built aspectj-aware bundles and products with several kinds of settings. So, I can say that the patch is sufficient for my purposes. What are the chances that this can get into 3.6 before the api freeze? If this can make it into 3.6, then I can remove a massive amount of unmaintainable code from AJDT that includes 3 wizards that are essentially copies of pde.ui code (I know that Chris would be happy about this). The only annoying part of this whole exercise has been the fact that org.apache.tools.ant.taskdefs.Javac is built to ignore any source files that do not end with .java. Perhaps this can be changed in future versions of ant.
I changed the default for -log and @arg file to be true(In reply to comment #8) > Thanks for the quick response. > > (In reply to comment #7) > > compilerAdapter.useLog : set to "true" to receive the -log argument > > compilerAdapter.useArgFile : set to "true" to receive the '@' argument file > Any reason not to set these to true by default? The compilers that I work with > are basically JDT-derived and so should be able to accept all arguments that > the jdt compiler accepts. And I'd bet that compiler adapters that would not > accept these arguments would just ignore them. (This is a minor point though.) I changed the default to true. The thing to be careful is supporting comments in the argument file using '#'. PDE/Build passes encoding and access rules to the jdt compiler adapter using comments that start with #ADAPTER#ACCESS# and #ADAPTER#ENCODING#. I release my patch here for the I Build, but it looks like your test patch is incomplete. Also, if possible can you write the test to use AntUtils to validate the ant script so that the tests don't break easily if the xml changes a little. See ScriptGenerationTests#testSimpleClasspath and testBug238177 as examples.
Created attachment 160713 [details] Updated test cases. Updated test cases. Added a few more, and now using AntUtils as described in the previous comment.
Comment on attachment 160713 [details] Updated test cases. patch released with minor changes
(In reply to comment #10) > The only annoying part of this whole exercise has been the fact that > org.apache.tools.ant.taskdefs.Javac is built to ignore any source files that do > not end with .java. Perhaps this can be changed in future versions of ant. Andrew, do you guys have a work around for this? It looks like the CompilerAdapter could get Javac#getSrcDir() and redo the source scan yourself. It would be annoying having to scan a second time, but I think it would work. For the record, Andrew raised https://issues.apache.org/bugzilla/show_bug.cgi?id=48829 I have released the tests, so I think this is done.
(In reply to comment #14) > Andrew, do you guys have a work around for this? I do have a workaround, but it's not particularly pretty. Thanks for getting this resolved.
*** Bug 147432 has been marked as a duplicate of this bug. ***
Hi I tried to just add the two lines to the build.properties of my plugin: compilerAdapter=org.eclipse.ajdt.core.ant.AJDT_AjcCompilerAdapter sourceFileExtensions=*.java, *.aj But the .project contains still the lines: ... <buildCommand> <name>org.eclipse.jdt.core.javabuilder</name> <arguments> </arguments> </buildCommand> ... If I now run the headless buckminster build, then the classes dont get woven. Do you have any examples, on how to set the thins up usin eclipse 3.6? Kind Regards, Alain.
I have not tried this out on Buckminster, and I know little about how it works, so I am not sure it this mechanism will be sufficient for Buckminster builds. However, Buckminster relies on eclipse project natures and eclipse builders. So, you need to make sure that your project is an AspectJ project and that the ajnature and builder are included in the ,project file. I do not believe that Buckminster uses the build.properties file at all (but I may be mistaken about that). (In reply to comment #17) > Hi > > I tried to just add the two lines to the build.properties of my plugin: > > compilerAdapter=org.eclipse.ajdt.core.ant.AJDT_AjcCompilerAdapter > sourceFileExtensions=*.java, *.aj > > But the .project contains still the lines: > > ... > <buildCommand> > <name>org.eclipse.jdt.core.javabuilder</name> > <arguments> > </arguments> > </buildCommand> > ... > > If I now run the headless buckminster build, then the classes dont get woven. > > Do you have any examples, on how to set the thins up usin eclipse 3.6? > > Kind Regards, Alain.