Bug 147831 - [compiler] failed to find classes wrapped in a bundle
Summary: [compiler] failed to find classes wrapped in a bundle
Status: RESOLVED FIXED
Alias: None
Product: PDE
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 enhancement with 1 vote (vote)
Target Milestone: 3.7 M7   Edit
Assignee: Curtis Windatt CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed, noteworthy
: 111238 149528 154562 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-06-20 03:39 EDT by keanu CLA
Modified: 2012-04-29 09:21 EDT (History)
13 users (show)

See Also:


Attachments
witmate_projects.zip (1.08 MB, application/x-zip-compressed)
2006-06-20 03:45 EDT, keanu CLA
no flags Details
PDE Patch which caches wrapped JARs in referenced external plug-ins (3.87 KB, patch)
2011-03-10 10:55 EST, Florian Albrecht CLA
no flags Details | Diff
Patch for caching wrapped JARs in referenced external bundles (6.71 KB, patch)
2011-03-10 14:16 EST, Florian Albrecht CLA
curtis.windatt.public: iplog+
Details | Diff
Improved Fix (10.28 KB, patch)
2011-03-10 17:30 EST, Curtis Windatt CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description keanu CLA 2006-06-20 03:39:09 EDT
Symptom:
eclipse compiler does not find the classes and brings compile error.
A test code try to look up a bundle in which a couple of libraries are added. Classes wrappted in the libraries are exposed via wrapping bundle.
To my best knowledge, osgi r4 supports exposing packages wrapped in a bundle. But eclipse compiler fails to find the expected class and brings a compile error.

Regeneration:
1. import projects attached
- org.eclipse.equinox.log
- witmate.deploy
- witmate.test

2. Then compile error occurs with the red x sign in the project "wetmate.test"
Message says "The import witmate.core cannot be resolved".
The package is in the jar "witcore-all.jar", which is wrapped in the bundle "WitCoreBundle-602.0.0.jar". The bundle is in the target directory.
Comment 1 keanu CLA 2006-06-20 03:45:21 EDT
Created attachment 44901 [details]
witmate_projects.zip

This is my working environment. 
1. import projects in the zip file
2. set target platform as dir"witmate.deploy/target"

my environment
- eclipse 3.2 RC7
- j2se 1.4.2
- Windows XP Professional
Comment 2 Pascal Rapicault CLA 2006-06-20 09:23:45 EDT
You are correct, this scenario is supported by the equinox runtime, however it is not possible to compile against such bundles because of limitations of java compilers (this stands for javac or the eclipse compiler).

Moving to JDT as this is a compiler limitation.
Comment 3 Andrew Niefer CLA 2006-07-05 12:45:46 EDT
*** Bug 149528 has been marked as a duplicate of this bug. ***
Comment 4 Michael Giroux CLA 2006-08-28 13:05:20 EDT
(In reply to comment #2)
> Moving to JDT as this is a compiler limitation.

WRT nested jars, if this cannot be fixed in 3.2, would it be possible to add some form of warning to the plugin and feature export wizards to inform the developer classes contained in nested jars will be hidden from projects that reference the plugin that is about to be exported.

Knowing that classes in a nested jar could not be found by the compiler would have saved me a lot of time.  I got pretty enthused by the trend to distribute as packed jars, and switched to that form.  When doing so, it would have helped if the export wizard recommended that I *not* build runtime jars.

Note that building runtime jars and nesting in a distribution jar has two issues, one is performance (described in a help topic somewhere) and the other is this compiler visibility issue.

Possibly the dependency analysis wizard could detect when plugins that are referenced contain nested jars and issue a warning that some classes might not be resolved.

Comment 5 Wassim Melhem CLA 2006-08-28 22:29:59 EDT
*** Bug 154562 has been marked as a duplicate of this bug. ***
Comment 6 Philipe Mulet CLA 2006-09-13 11:29:26 EDT
What would it take to be able to consume nested jars ? As for the warning creation, this is not the compiler job. Pascal, shouldn't you readopt the bug ?
Comment 7 Olivier Thomann CLA 2007-01-08 10:07:06 EST
This is rather an enhancement since this was never supported and is considered as a new feature.
A workaround is to unjar the jars.
We would need to see how we can support this efficiently.
Comment 8 Michael Giroux CLA 2007-01-08 10:23:42 EST
(In reply to comment #7)
> This is rather an enhancement since this was never supported and is considered
> as a new feature.

The problem is that is almost works sometimes.

If plug-in A references plug-in B, and B contains a nested library, then we get confusing results.

a. plug-in A works as expected when installed  -- this leads a developer to think the packaging of A and B are fine.

b. plug-in A can be build if plug-in B is also open in the workspace -- this also leads the developer to believe that packaging is fine.

c. plug-in A fails to build if you close the project for plug-in B -- here is where things get confusing.

Whether this is fixed or not, there should be some form of warning message that helps the developer understand why the classes are not found.  In comment #4 I suggested that a build warning could be issued when plug-in B is exported to remind the developer that classes in the nested libraries will not be visible to the compiler when building dependent plug-ins.

The fact that the classes are visible at runtime but not to the compiler can result in a lot of lost time.  Perhaps the dependency analysis could be enhanced to display error messages for classes residing in nested libraries.
Comment 9 Florian Albrecht CLA 2011-03-09 11:27:57 EST
Well, for our company, this is a real "show stopper". Even Maven/Tycho can resolve such wrapped JARs correctly when building dependent bundles!

So, we have this situation (even in Eclipse 3.6!), mainly as described above:

- having the "core" project (containing wrapped JARs and exporting some of their packages) in workspace, everything works fine.

- Removing the "core" project from workspace, thus having it only in our common "Company Target Platform" as a JAR, the developer gets compile errors in Eclipse. But this is our main usage scenario - a developer should not have to have all bundles in his workspace just for being able to work on a single one.

- building the dependent project on command line with Maven/Tycho (which uses our common Target Platform for resolving), everything works fine.


I don't understand why the Eclipse Compiler should not be able to fully conform to OSGi standards. Perhaps have a look at Tycho? It's no rocket science at all to resolve these wrapped JARs...
Comment 10 Olivier Thomann CLA 2011-03-09 13:24:57 EST
Florian,

What build are you using ?
If you are using 3.7 I-build, could you please try this?
1) Add this to the command line inside the VM arguments:
-DresolveReferencedLibrariesForContainers=true

2) In your MANIFEST.MF file, copy the entry "Bundle-Classpath:" in which you have the nested jars to "Class-path:". One of the issue here is that the compiler doesn't know anything about this entry Bundle-Classpath:.

Could you please confirm that doing this fixes your issue ? Then we can see how to "fix" this inside the compiler.
Comment 11 Olivier Thomann CLA 2011-03-09 13:55:37 EST
Forget my last comment. I need to do more investigation.
Comment 12 Florian Albrecht CLA 2011-03-10 10:55:37 EST
Created attachment 190874 [details]
PDE Patch which caches wrapped JARs in referenced external plug-ins

After thinking about this issue, I came to the conclusion that perhaps PDE is the right location for a fix. PDE resolves legacy JARs in plug-in projects that are in your workspace and adds them to the "Plug-in Dependencies" Classpath Container; so that's where I'd like to see them also for external plug-ins. 

The basic concept of my provided patch is creating a ".libcache" folder in the state location of PDECore (.metadata/org.eclipse.pde.core) and there a folder for each external plug-in wrapping legacy JARs. The wrapped JARs are extracted to there and added to the Classpath Container contents. 

Notice that there are some issues left with this patch (maybe even the whole concept is "not okay" for PDE):

- when will the cached JARs be deleted?
- make this behaviour configurable as a PDE preference

For a better design, it could also be neccessary to put the JAR caching logic into a new builder which can be added to projects. But for us, this patch works fine at the moment.
Comment 13 Curtis Windatt CLA 2011-03-10 11:35:53 EST
(In reply to comment #12)

The PDE fix is the correct approach.  We need a way for the PDE container to point to the jarred library.  For workspace projects, we already do this.  For unjarred external bundles we add the jarred libraries to the path.  For nested jars, unless JDT has an alternative solution, we have extract them ourselves.

The PDE Container is not able to manage the cache of extracted libraries.  It has no way of knowing whether another container is using a given library.  Instead, we need a global manager that can watch the PluginRegistry/ExternalModelManager for changes and clear the cache at that time.

As long as the jars are extracted only as needed and the cache is clear when the external models change, we wouldn't need a preference.  The peformance hit of extraction would only affect users who have missing libraries on the classpath.
Comment 14 Olivier Thomann CLA 2011-03-10 13:28:54 EST
Moving to PDE/UI.
The batch compiler could only work if the classpath creates by PDE/Build would also contain the appropriate jars.
Comment 15 Florian Albrecht CLA 2011-03-10 14:16:47 EST
Created attachment 190902 [details]
Patch for caching wrapped JARs in referenced external bundles

I now moved the JAR caching logic directly to ExternalModelManager (and slightly improved it). When the target platform is initialized, the cache directory is checked for unzipped JARs which are no longer needed. 
The Classpath Container asks the external model manager for cached JAR files for a given external bundle if one is encountered, so JAR caching will be lazy.

I'm sure there's room to optimize the code... ;-)

Curtis, please give me a short feedback if the patch could now be applied to PDE, or what else is required to have this fixed in a future Eclipse version. Thanks!
Comment 16 Curtis Windatt CLA 2011-03-10 14:35:46 EST
Thanks for the fast update Florian.  The second patch is very similar to what I envisioned and I don't see any major issues at first glance.  It will require some more testing and possibly tweaking before it can be committed, but I will mark this bug for M7 inclusion.
Comment 17 Florian Albrecht CLA 2011-03-10 14:43:23 EST
Great, looking forward to it! :-)
Comment 18 Curtis Windatt CLA 2011-03-10 17:30:35 EST
Created attachment 190936 [details]
Improved Fix

1) Encapsulated code into it's own type
2) Fixed NPEs if the library is missing from the JAR
3) Added additional comments
4) Added deletion of empty directories
Plus a few little tweaks to the code.

With these changes, it is working great for me.  I had hoped that none of this code would be hit in the standard Eclipse target platform, however some of the Eclipse bundles (ui.ide, workbench) list libraries on their classpath, but don't include them in their published jars.  The performance hit appears to be trivial, but it does exist, as we have to open the jar to see if the libraries are there.
Comment 19 Curtis Windatt CLA 2011-03-10 17:32:33 EST
This will be committed early M7, either tomorrow afternoon or Monday.  If anyone else is able to test the patch it would be appreciated as there could be edge cases it does not handle properly.
Comment 20 Curtis Windatt CLA 2011-03-14 10:48:26 EDT
Applied the updated fix to HEAD.
Comment 21 Curtis Windatt CLA 2011-03-25 11:11:02 EDT
*** Bug 111238 has been marked as a duplicate of this bug. ***
Comment 22 Curtis Windatt CLA 2011-03-25 11:14:56 EDT
Note that this feature will only extract jarred libraries.  It does not consider the extra classpath entries in the build.properties.
Comment 23 Alexander Fischer CLA 2011-06-07 03:43:17 EDT
What is your preferred solution for Eclipse Helios (SR2)?
Should I patch all my wrapper-bundles with embedded jars (unpacking the jars and repacking the bundle)?