Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 323090 - Eclipse-ExtensibleAPI often doesn't work when launching from within Eclipse, fragment Require-Bundle plugins do not resolve
Summary: Eclipse-ExtensibleAPI often doesn't work when launching from within Eclipse, ...
Status: CLOSED WONTFIX
Alias: None
Product: PDE
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.4.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: PDE-UI-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-18 17:59 EDT by Chris Lee CLA
Modified: 2019-09-09 02:38 EDT (History)
3 users (show)

See Also:


Attachments
set of projects that attempt (but fail) to repro the bug... (75.41 KB, application/x-zip-compressed)
2010-08-18 18:00 EDT, Chris Lee CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lee CLA 2010-08-18 17:59:52 EDT
Build Identifier: 20100218-1602

We've been having a recurring issue with a plugin fragment that often has trouble resolving when we try to launch our app from the Eclipse PDE. This problem existed in Eclipse 3.4.1 and 3.4.2, and seems to still exist in Eclipse 3.5.2

I've narrowed it down to the existence of the "Require-Bundle" header in the fragment's manifest. In general, when it exists, our app cannot resolve the fragment because each dependency listed logs this error: "Constraints from the fragment conflict with the host".

Now, this doesn't happen all the time. After we initially load all of our projects into the workspace, there are no problems. However, anytime the fragment's manifest is modified and the PDE rebuilds necessary plugins (even if it's just touched with no real modification), then we suddenly start getting errors, and it seems the only way to make them stop happening is to either (a) remove and re-import all the projects, or (b) change the default JRE we use to compile. Note that cleaning all projects does not resolve the issue.

My recent discovery was that removing the "Require-Bundle" stuff from the fragment lets the bundle resolve properly, but adding it back re-introduces the problem (similar to just touching the file).

Reproducible: Always

Steps to Reproduce:
I tried to create a sample app to repro this outside of our environment (attached), but it doesn't reproduce.  I'm hoping that the attached projects and description is at least enough to point to a potential solution though...

Summary description of attached projects: 
MyLibs - java library
MyPlugin/MyFragment - host and fragment. MyPlugin exposes the packages in MyLibs to the world, and this particular fragment depends on MyLibs being imported into the workspace. In our environment, we often swap to use the fragment that refers to MyLibs as a jar.
HelloWorld - contains some basic UI actions - shared UI bits so both our RCP apps and IDE integrations can use it. Depends on MyLibs through the interface provided by MyPlugin. Includes launch config.
MyApp - RCP app
Comment 1 Chris Lee CLA 2010-08-18 18:00:47 EDT
Created attachment 176941 [details]
set of projects that attempt (but fail) to repro the bug...
Comment 2 Chris Lee CLA 2010-08-18 19:14:19 EDT
Some more information about how this repros in our environment (still can't repro in attachment though): 

I've found a simpler workaround to the problem than reimporting projects or changing the JRE - touch the host plugin's manifest file.

If (out of the host and fragment's manifest) the fragment's manifest is the last one modified, all the plugins required by the fragment will fail with the "Constraints from the fragment conflict with the host" errors. If the host's manifest is the last one modified, everything works fine.

Any ideas why this works and a "Clean/Rebuild" does not work? Any ideas why this problem is occurring at all?
Comment 3 Chris Lee CLA 2010-09-22 18:41:44 EDT
I've managed to debug into this issue more (in our debug environment, not in the attached sample), eventually got into some of the bundle loading stuff, and determined that it's related to some sort of bundle state stored in the workspace related to my launch configuration.  

If I duplicate my launch configuration (while I'm in a "failure" state) and run the new one, it will work fine.

Specifically, plugin resolution state is being read from: 
C:\Workspaces\MyWorkspace\.metadata\.plugins\org.eclipse.pde.core\TestLaunch\org.eclipse.osgi\.state.26
by org.eclipse.osgi.internal.resolver.StateReader.readState / readBundleDescription reads in a 'false' RESOLVED state for my fragment's bundle.

If I make no code changes, duplicate the TestLaunch launch configuration, and run using that configuration, it generates 'true' as the RESOLVED state for my fragment's bundle using org.eclipse.osgi.internal.resolver.StateImpl.resolveBundle, and I can launch successfully.
Comment 4 Chris Lee CLA 2010-09-22 19:15:59 EDT
Updating platform version to 3.4.2 - Although we're using Eclipse 3.5.2 for our debug environment, it seems that the problem is caused by something in the target environment (3.4.2).  This still doesn't seem to affect the sample I attached though...
Comment 5 Chris Lee CLA 2010-09-22 20:35:21 EDT
Looking in org.eclipse.osgi.internal.module.ResolverImpl, it seems there's a function 'addDevConstraints' called during resolution, which normally does nothing (since 'developmentMode' is false).

If I have my workspace setup to reproduce the problem and set developmentMode=true through the debugger, then the problem doesn't happen - another way to workaround the problem.

It seems there's a way to automatically set this to true: 
 
org.eclipse.osgi.framework.internal.core.Constants.DEVELOPMENT_MODE.equals(platformProperties[0].get(org.eclipse.osgi.framework.internal.core.Constants.OSGI_RESOLVER_MODE));

How do I do this?
Comment 6 Thomas Watson CLA 2010-09-23 10:12:51 EDT
Another workaround that should work is to clear the configuration on in your launch configuration.  This can be done on the "Configuration" tab.  There is a check box under "Configuration Area" for "Clear the configuration area before launching".

At first I was confused because I thought your problem was with the fragment resolving in your workspace.  And just to confirm, you are not seeing any error markers in the fragment project, correct?

It seems like your issue is when you actually launch eclipse then your fragment is no longer allowed to resolve.  So this is really an issue with resolving your fragment at runtime when launching from a workspace after you have touched the fragment's manifest.  Here is what happens in this case.

1) When launching with a launch configuration from eclipse the runtime checks to see if a bundle manifest has been modified.  If so then it forces the bundle to be uninstalled.

2) During launch it is detected that a bundle is missing (that got uninstalled in step 1) and the missing bundle is reinstalled.  This is necessary to force the bundle to be reparsed and reloaded with the new content.

3) The framework attempts to resolve the newly installed bundle (fragment in your case).  The issue with this fragment case is that it is adding a new requirement to its host.  In this case the host is already resolved.  We cannot dynamically attach the fragment to the host that is already resolved because the new requirement may corrupt the class space of the resolved host.  The only way to attach such a fragment is to force the host to refresh.

You can confirm this by adding the -console option to the program args and running the "ss" command.  Find your host bundle ID and the call "refresh <host id>".  That should force the host to re-resolve and allow the fragment to attach.

When launching a built platform that uses p2, the p2 simple configurator will detect such a scenario and perform the refresh on the host bundle for you.
Comment 7 Chris Lee CLA 2010-09-23 12:27:01 EDT
(In reply to comment #6)
> Another workaround that should work is to clear the configuration on in your
> launch configuration.  This can be done on the "Configuration" tab.  There is a
> check box under "Configuration Area" for "Clear the configuration area before
> launching".

[Chris] This indeed solves the problem as well, and does it in a way I can easily distribute the fix :)

> At first I was confused because I thought your problem was with the fragment
> resolving in your workspace.  And just to confirm, you are not seeing any error
> markers in the fragment project, correct?

[Chris] Correct - the projects are always building properly. The problem only occurred when the fragment's manifest was modified after the host's manifest.

> It seems like your issue is when you actually launch eclipse then your fragment
> is no longer allowed to resolve.  So this is really an issue with resolving
> your fragment at runtime when launching from a workspace after you have touched
> the fragment's manifest.  Here is what happens in this case.
> 1) When launching with a launch configuration from eclipse the runtime checks
> to see if a bundle manifest has been modified.  If so then it forces the bundle
> to be uninstalled.
> 2) During launch it is detected that a bundle is missing (that got uninstalled
> in step 1) and the missing bundle is reinstalled.  This is necessary to force
> the bundle to be reparsed and reloaded with the new content.
> 3) The framework attempts to resolve the newly installed bundle (fragment in
> your case).  The issue with this fragment case is that it is adding a new
> requirement to its host.  In this case the host is already resolved.  We cannot
> dynamically attach the fragment to the host that is already resolved because
> the new requirement may corrupt the class space of the resolved host.  The only
> way to attach such a fragment is to force the host to refresh.
> You can confirm this by adding the -console option to the program args and
> running the "ss" command.  Find your host bundle ID and the call "refresh <host
> id>".  That should force the host to re-resolve and allow the fragment to
> attach.

[Chris] What I've done to try this is put a breakpoint in my Application.run function (so the app stays alive while I run the console). 'ss' shows my host bundle is "Resolved" and my fragment bundle is "Installed". After the refresh, it shows both resolved (and attached with master/fragment bundle id references), and it's fixed.

> When launching a built platform that uses p2, the p2 simple configurator will
> detect such a scenario and perform the refresh on the host bundle for you.


Thanks for the help Thomas - hopefully this is enough information so that this bug can be resolved in the code, eliminating the need for one of these workarounds. For us, updating our launch targets to always "Clear the configuration area before launching" is good enough for now.
Comment 8 Eclipse Webmaster CLA 2019-09-06 15:32:48 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 9 Eclipse Webmaster CLA 2019-09-06 15:36:28 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 10 Julian Honnen CLA 2019-09-09 02:38:35 EDT
Please remove the stalebug flag, if this issue is still relevant and can be reproduced on the latest release.