Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 268881

Summary: Use Import-package headers instead of Required-Bundle
Product: [Technology] SWTBot Reporter: Ivica Loncar <iloncar.ml>
Component: SWTBotAssignee: Project Inbox <swtbot-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: KetanPadegaonkar, mseashore, will.horn
Version: 2.0.0-dev   
Target Milestone: 2.0.0   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on: 266962, 269888    
Bug Blocks:    
Attachments:
Description Flags
example projects
none
example patch using import-package none

Description Ivica Loncar CLA 2009-03-16 17:17:15 EDT
Please use Import-packages header instead of  Require-Bundle header, at least for non eclipse projects and/or APIs. Examples are junit, logging and commons libraries.

Reason:
In our target platform we already have all the required libraries. The problem is that they come from other bundle repository and they have different names. The API and versions are the same or compatible, but bundle names are different.

If swtbot would use import-package instead of require-bundle we wouldn't have to change anything, we could reuse those bundles and we could use the same target platform that we deploy on for testing purposes also.
Comment 1 Will Horn CLA 2009-03-31 19:47:51 EDT
hamcrest is another one
Comment 2 Will Horn CLA 2009-03-31 20:06:42 EDT
Ah, just noticed 269888.  I imagine part of the difficulty with this is that the Eclipse org.junit4 bundle exports the hamcrest libraries and import-package could get wired to that bundle instead of the proper full hamcrest bundle.

Ketan, did you have any success? I can take a stab at it if you would like.
Comment 3 Ketan Padegaonkar CLA 2009-03-31 20:16:19 EDT
Sure go ahead take a stab, but the major issue is to figure out which bundle to wire up with.

OSGi allows your Import-Package to wire up to a particular bundle, and swtbot could wire up with orbit's bundles, but that will certainly not work with a bundle you downloaded elsewhere. Also this approach is not any better than Require-Bundle.

I'll be marking this one as won't fix if you're unable to provide something that works well.
Comment 4 Ketan Padegaonkar CLA 2009-03-31 20:19:12 EDT
Just to add, it's possible to do an import package for all but hamcrest bundles, but that'd still not fix the problem for hamcrest, so you're probably better off either modifying swtbot manifests yourself OR use the bundles that swtbot ships with (in addition to or instead of your bundles)
Comment 5 Will Horn CLA 2009-04-01 14:25:41 EDT
Yeah, this is not any easy combination of bundles to work with.  I'm curious, is there any problem with org.junit4 and org.hamcrest both providing the same classes?  The OSGi spec mentions something about shadowing when you use require-bundle, but couldn't tell if it is a problem.

I think it might help if the org.junit4 plugin added an attribute to it's hamcrest exports and also imported the packages, e.g.

Export-Package: junit.extensions;version="4.5.0",
 junit.framework;version="4.5.0",
 junit.runner;version="4.5.0",
 junit.textui;version="4.5.0",
 org.hamcrest;version="1.1.0";provider="junit",
 org.hamcrest.core;version="1.1.0";provider="junit",
 org.hamcrest.internal;version="1.1.0";provider="junit";x-internal:=true,
 ...
Import-Package: org.hamcrest;version="1.1.0",
 org.hamcrest.core;version="1.1.0",
 org.hamcrest.internal;version="1.1.0"

If my understanding is correct, this would prevent other bundles who import org.hamcrest (e.g. swtbot) from accidentally getting wired to org.junit4 for that package when another full hamcrest bundle is available.  Then in the case that a hamcrest bundle is not available, the wiring would fall back to org.junit4.
Comment 6 Will Horn CLA 2009-04-01 14:28:56 EDT
Created attachment 130599 [details]
example projects

Three projects that describe what I am talking about:
org.hamcrest - SWTBot's hamcrest bundle
org.junit4 - Eclipse 3.5M6's junit bundle, with the described modifications to the manifest
osgitest - Example bundle that imports org.hamcrest and org.junit and is correctly wired to org.junit4 for the org.junit package and org.hamcrest for the org.hamcrest package
Comment 7 Will Horn CLA 2009-04-01 14:31:25 EDT
P.S. Obviously this would require a change in the org.junit4 bundle which Eclipse may not be willing to make.  But I will request it if you think it looks good.
Comment 8 Will Horn CLA 2009-04-02 17:34:51 EDT
(In reply to comment #5)
> I'm curious,
> is there any problem with org.junit4 and org.hamcrest both providing the same
> classes?  The OSGi spec mentions something about shadowing when you use
> require-bundle, but couldn't tell if it is a problem.

This is a problem.  After installing SWT Bot on 3.5M6 (I used the version provided at the EclipseCon tutorial), a simple test will throw a LinkageError:

import static org.hamcrest.Matchers.is;

import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(SWTBotJunit4ClassRunner.class)
public class LinkageTest {
	
	@Test
	public void test() throws Exception {
		org.junit.Assert.assertThat("asdf", is("asdf"));
	}
}

Note the use of the JUnit assertThat rather than the Hamcrest one.  The problem is that there are two different versions of org.hamcrest.Matcher (one in the org.junit4 bundle and one in the org.hamcrest bundle).

I can submit a separate bug, but I think these issues are closely related.  We really need the hamcrest bundle to completely shadow the org.junit4 version of the org.hamcrest package.
Comment 9 Ivica Loncar CLA 2009-04-05 06:51:47 EDT
Please do not just close this bug report.

It seems that the issues with junit and hamcrest could get fixed in the near future ( == couple of monhts in eclipse time ;-) )

I have added dependency on a bug 266962
Comment 10 Will Horn CLA 2009-04-05 19:01:47 EDT
(In reply to comment #5)
> I think it might help if the org.junit4 plugin added an attribute to it's
> hamcrest exports and also imported the packages

I had a discussion with OSGi guru Peter Kriens and this is not a valid workaround.  You cannot rely on the attribute matching in the way I suggested.  

But he also added that it is wrong for a bundle to export a package that is not complete.  In his words, "The basic idea in OSGi is that packages are specification and well versioned."

So there is a core problem with org.junit4 exporting the partial org.hamcrest package.  Hopefully bug 266962 will fix this and do so in a way that is compatible with non-Eclipse hamcrest bundles.

In the meantime, I've filed http://bugs.eclipse.org/271257 for the issue I mentioned in Comment #8 which needs to be addressed regardless of whether this bug is fixed.
Comment 11 Ketan Padegaonkar CLA 2009-04-28 18:15:23 EDT
Will, would you like me to close this as wont fix because of the way hamcrest is packaged ? I'm not really hopeful of this getting fixed unless hamcrest fixes its packaging.
Comment 12 Ketan Padegaonkar CLA 2009-04-28 18:48:08 EDT
*** Bug 271257 has been marked as a duplicate of this bug. ***
Comment 13 Will Horn CLA 2009-04-28 19:26:56 EDT
(In reply to comment #11)
> Will, would you like me to close this as wont fix because of the way hamcrest
> is packaged ? I'm not really hopeful of this getting fixed unless hamcrest
> fixes its packaging.
I have no other ideas for getting hamcrest via import-package.  However, I would still strongly recommend using import-package for junit and log4j packages.  I would try to offer a patch, but I never was able to build from source http://dev.eclipse.org/mhonarc/newsLists/news.eclipse.swtbot/msg00510.html

For the hamcrest case, what is going to happen once Eclipse rolls out the new org.junit4 that requires org.hamcrest.core (http://bugs.eclipse.org/266962)?  SWT Bot still needs the full hamcrest so there will be a conflict between the uber org.hamcrest bundle from SWT Bot and the partial package org.hamcrest.core that comes with the SDK.  LinkageErrors like http://bugs.eclipse.org/271257 will start popping up again I think.

Comment 14 Ketan Padegaonkar CLA 2009-04-28 23:00:59 EDT
I've written to the hamcrest-dev list to see if they can help resolve this:

http://groups.google.com/group/hamcrest-dev/browse_thread/thread/3c2357667c5bc005
Comment 15 Will Horn CLA 2009-04-29 19:00:53 EDT
(In reply to comment #14)
> I've written to the hamcrest-dev list to see if they can help resolve this:
> 
> http://groups.google.com/group/hamcrest-dev/browse_thread/thread/3c2357667c5bc005

I think their replies are as expected.  It would be a breaking API change for them to rename the packages.  Assuming they don't fix it, I think SWT Bot is in a difficult situation.  

Eclipse SDK has org.junit4 which now requires and reexports org.hamcrest.core.  That means you have to assume OSGi can choose org.hamcrest.core as the exporter of the org.hamcrest package.  This effectively blocks the use of the org.hamcrest package classes in hamcrest integration and hamcrest library.

I am planning to work around this in my RCP app by removing the org.junit4 and org.hamcrest.core that comes with Eclipse.  I will then create my own single org.hamcrest bundle with everything I need, and my own org.junit4 bundle which imports the hamcrest packages instead of requiring org.hamcrest.core.  The org.eclipse.jdt.junit4.runtime bundle will wire to my custom bundles and all will be well.

SWT Bot, on the other hand, is designed to be installed in the Eclipse IDE so you don't have the ability to discard the official org.junit4 and org.hamcrest.core bundles.  I don't see how you can get the library and integration jars to work in this case!

The only solution I can see is to make hamcrest core, library, and integration a single bundle in orbit.  Eclipse would need to include this bundle in the SDK and have org.junit4 use it.  This would increase the size of the SDK slightly so I'm sure there will be opposition.
Comment 16 Will Horn CLA 2009-04-29 19:33:09 EDT
I reopened http://bugs.eclipse.org/271157 because that is the issue we are dealing with here.
Comment 17 Will Horn CLA 2009-04-30 14:02:29 EDT
Given Thomas' response on bug 271157, it actually should be possible to use Import-Package even with hamcrest.  There are a few issue with the hamcrest bundles which I have added to bug 271348 (I think this bug is now dependent on 271348).
Comment 18 Will Horn CLA 2009-05-01 14:38:32 EDT
Created attachment 134096 [details]
example patch using import-package

Using the latest org.junit4 from JDT and hamcrest/qdox/log4j from orbit, I was able to replace Require-Bundle with Import-Package.
Comment 19 Ketan Padegaonkar CLA 2009-07-11 05:16:46 EDT
Marking as fixed. Please reopen if you find an some issue.
Comment 20 Will Horn CLA 2009-07-11 12:21:40 EDT
(In reply to comment #19)
> Marking as fixed. Please reopen if you find an some issue.
Did you see my patch in comment 18?  It should now be possible to use Import-Package instead of Require-Bundle.  If you prefer to leave Require-Bundle, then WONTFIX is more appropriate than RESOLVED.
Comment 21 Ketan Padegaonkar CLA 2009-07-11 14:19:20 EDT
I've fixed all manifests (except tests for now). If there's any particular manifest that you think I've missed, let me know and I'll fix it.
Comment 22 Will Horn CLA 2009-07-11 14:19:59 EDT
(In reply to comment #20)
Sorry, I was looking at outdated code.  Thanks for fixing this.