Bug 114146 - When ajc crash on one file, should continue on for the rest of files
Summary: When ajc crash on one file, should continue on for the rest of files
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P5 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-28 12:46 EDT by Michelle Xue CLA
Modified: 2007-10-23 11:25 EDT (History)
1 user (show)

See Also:


Attachments
file that causes ajcore dump (8.94 KB, application/octet-stream)
2005-11-18 13:21 EST, Michelle Xue CLA
no flags Details
file that causes ajcore dump (13.65 KB, application/octet-stream)
2005-11-18 13:22 EST, Michelle Xue CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michelle Xue CLA 2005-10-28 12:46:19 EDT
I encounter problems when I try to run ajc on  a jar file or a diretory of
files, once ajc crash on one file, it completetly dies.  It will be useful that
ajc can continue run on the rest of the files.
Comment 1 Matthew Webster CLA 2005-11-17 05:56:59 EST
Can you give some details of how ajc "crashes". Do you get an exception or an 
error message.
Comment 2 Michelle Xue CLA 2005-11-17 12:27:05 EST
It generates ajcore dump.

--- Dump Properties ---

Dump file: ajcore.20051116.114233.674.txt

Dump reason: org.aspectj.apache.bcel.classfile.ClassFormatException

Dump on exception: true

Dump at exit condition: abort

---- Exception Information ---

org.aspectj.apache.bcel.classfile.ClassFormatException: Invalid byte tag in
constant pool: 108

            at
org.aspectj.apache.bcel.classfile.Constant.readConstant(Constant.java:145)

            at
org.aspectj.apache.bcel.classfile.ConstantPool.<init>(ConstantPool.java:103)

            at
org.aspectj.apache.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:254)

            at
org.aspectj.apache.bcel.classfile.ClassParser.parse(ClassParser.java:162)

            at org.aspectj.weaver.bcel.Utility.makeJavaClass(Utility.java:365)

            at
org.aspectj.weaver.bcel.UnwovenClassFile.getJavaClass(UnwovenClassFile.java:63)

            at org.aspectj.weaver.bcel.BcelWeaver.addClassFile(BcelWeaver.java:280)

            at org.aspectj.weaver.bcel.BcelWeaver.addClassFile(BcelWeaver.java:295)

            at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.initBcelWorld(AjBuildManager.java:533)

            at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:151)

            at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:102)

            at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:109)

            at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60)

            at org.aspectj.tools.ajc.Main.run(Main.java:291)
Comment 3 Matthew Webster CLA 2005-11-18 06:37:33 EST
The symptoms suggest that the class file is either corrupted or not a valid 
Java class. Can you confirm which version and build of AspectJ you are using? 
Could you attach an example of a file that causes this failure.
Comment 4 Michelle Xue CLA 2005-11-18 12:48:21 EST
I am usaing version 1.2.1, the latest stable release.  I don't know the build
number.  Sorry, I can't give you the file that causes the problem. But it's
possible that the file is corrupted.  However, it's still very useful to have
ajc skip the corrupted file.  
Comment 5 Michelle Xue CLA 2005-11-18 13:21:38 EST
Created attachment 30247 [details]
file that causes ajcore dump
Comment 6 Michelle Xue CLA 2005-11-18 13:22:05 EST
Created attachment 30248 [details]
file that causes ajcore dump
Comment 7 Michelle Xue CLA 2005-11-18 13:22:48 EST
I actually have two example files for you that causes ajcoredump
Comment 8 Matthew Webster CLA 2005-11-21 09:35:53 EST
Both attachments appear to be valid JDK 1.2 (major_version = 46) but corrupted class files: javap fails with the same error as AspectJ: invalid constant type: 108. Therefor I don't think this is an AspectJ bug. How are these classes being generated?

Recent versions of AspectJ produce a more meaningful exception message containing the name of the corrupted file. A further enhancement could be made so that an error message is issued. The compiler would then continue through the remaining files allowing you to determine which are corrupted but no byte-code would be generated. 

In general it is unsafe to produce a partially woven application e.g javac will not generate class files if errors are found. Might I suggest using Ant to copy those files known to be valid (using includ/exclude filters) to a temporary directory and then use iajc to weave them.
Comment 9 Michelle Xue CLA 2005-11-21 12:47:14 EST
I agreed with you that the file is corrupted, so it's not really a bug of ajc.  I mentioned earlier that I am applying aspectJ to the legacy binary code, it's a very useful enhancement that if it fails on one binary file, it will move on to the rest.  I think the user can decide if it's safe or not to use partially woven application.  This enhancement can broaden what aspectJ can do.  

I get those two examples files from weblogic example code.   
Comment 10 Matthew Webster CLA 2005-11-22 06:37:08 EST
If you pass invalid or corrupt byte-code to AspectJ we will issue and error. If any errors are issued during weaving we will not generate any byte-code e.g. the file specified using -outjar will not exist. This is because in general the resulting woven byte-code will not be a valid program and will not behave as the user desires. If a bug is reported it may be very difficult for the AspectJ team to find out what's wrong.
Comment 11 Michelle Xue CLA 2005-11-22 16:45:41 EST
I agree that normal behavior of aspectJ should just fail and stop weaving.  But could we have a option that force it continue even though it encounted corrupted file?  (Like ant, you can set something like fail-on-error to false, to force it to continue) 
Comment 12 Matthew Webster CLA 2005-11-28 09:47:46 EST
The use of a "proceedOnError" option with certain tools may produce output whose incompleteness can easily be determined i.e. file missing, ClassNotFoundException. With AspectJ the failure to apply cross-cutting function completely can produce far more subtle failures which are very difficult to diagnose especially if the original build messages are not available. A ClassFormatException is a rare and serious problem and if the code had been generated by AspectJ itself we would want to know as soon as possible.
Comment 13 Matthew Webster CLA 2006-07-07 10:53:27 EDT
Over the next week I propose to share the work in progress with the rest of the project. When complete you will need to follow these steps in the specified order:

1. Take a fresh AspectJ workspace in Eclipse 3.2 
2. Install JDK 1.5, JDK 1.3 and CDC 1.0/J2ME Foundation 1.0 using the Eclipse Wiki http://wiki.eclipse.org/index.php/Execution_Environments (or get a copy from me).
3. Associate the CDC-1.0, JSE-1.3 and JSE-1.5 Execution Environments with the appropriate JDKs (to avoid build warnings) using  the "Window > Preferences... > Java > Installed JREs > Execution Environments" page. 
4. Add an "ASPETCTJ_WORKSPACE" Path Variable that identifies the workspace e.g."C:\workspaces\org.aspectj-Restructure" using the "Window > Preferences... > General > Workspace > Linked Resources" preference page. 
5. Check out all the new plug-in projects (exact location to be decided).

Don't worry about the "The resource is a duplicate of ..." warnings which are cause by using linked source folders. Run "RunTheseBeforeYouCommitTests" in org.aspectj.all.tests as a "JUnit Test" (no need to use "JUnit Plug-in Test") using JDK 1.5 (it will use 1.3 by default). I will need to move some tests from 1.3 to 1.5 because they currently have hidden dependencies. You should be able to develop and test in the new structure then commit using the old (after a refresh of those projects). The names are a little long and may not be easy to distinguish but they are unique and you can always use "Check Out As...".

To work with the new bundle projects (unless changing dependencies or adding new projects):
1. Synchronize the old projects with HEAD
2. Refresh (and build) the new projects
3. Run org.aspectj.all.tests
4. Make changes to code in the new projects
5. When adding a test you will need to use the old project to add or modify data e.g. (because there are no linked folders)
6. Run org.aspectj.all.tests
7. Refresh the old projects
8. Synchronize the old projects with HEAD

The basic structure is:

	org.aspectj.ajde > org.aspectj.core > org.aspectj.weaver > org.aspectj.runtime

The org.aspectj.weaver module contains asm, bridge, loadtime, util and weaver. To make things easier each project re-exports its public dependencies. In addition there are fragments to hold code with a Java dependency that are automatically loaded with their host when using Java 5 e.g. runtime5 > runtime. Finally each bundle has an accompany tests bundle while org.aspectj.tests contains the compiler tests.

Project dependencies (.classpath) are replaced by bundle dependencies (META-INF/manifest.mf). In addition a bundle must be explicit about which packages other bundles can see i.e. its interface must be explicitly exported. There are 3 basic types of dependency:
1. Require-Bundle:	Used when a bundle has a hard dependency on another specific bundle implementation e.g. weaver and runtime or weaver.tests and weaver.
2. Import-Package:	Used when a dependency is provided by a different bundle during development than when it is deployed e.g. XML. The dependency can be optional as in the case of JRockit.
3. Bundle-Host:		Used for JRE-specific features. The fragment is logically part of the host bundle but is only loaded if its requirements are met. This allows weaver.tests to have a hard dependency on weaver but only when run with Java 5 is the weaver5 bundle loaded.

The main advantages of this approach are:
1. The project looks like what we ship and so AJDT can consume AspectJ directly from head (so can the Aspects Equinox Incubator and any other Eclipse/OSGi-based project).
2. Better management of dependencies such as Java 5, XML and JRockit.
3. Fewer build breaks because we actually build and test with the Execution Environment that we claim to support i.e. no accidental JDK 1.4 APIs!
Comment 14 Matthew Webster CLA 2006-07-07 11:22:02 EDT
Please ignore the last post, it was intended for a different bug report.