Stuart McCulloch wrote:
On 12/02/2008, Marshall Schor <[EMAIL PROTECTED]> wrote:
Hi Stuart -
I've made a super simple test example which shows the failure. Working
in Eclipse 3.2, I made a new Eclipse plugin, having one "main" class
which does one statement: it prints to sysout the value of SWT.ABORT.
To get access to SWT, it imports org.eclipse.swt.SWT. The POM for this
has one dependency declared
<dependency>
<groupId>org.eclipse.swt.win32.win32</groupId>
<artifactId>x86</artifactId>
<version>3.2.1-v3235</version>
<scope>provided</scope>
</dependency>
which is coming from
http://repo1.maven.org/maven2/org/eclipse/swt/win32/win32/x86/3.2.1-v3235/x86-3.2.1-v3235.pom
This compiles fine in Maven, but the manifest generated is missing the
import-package for org.eclipse.swt
Manifest-Version: 1.0
Export-Package: t
Built-By: schor
Build-Jdk: 1.6.0_02
Bundle-Version: 0.0.1
Tool: Bnd-0.0.227
Bundle-Name: Test and Learning Plugin
Bnd-LastModified: 1202751928745
Created-By: Apache Maven Bundle Plugin
Bundle-ManifestVersion: 2
Bundle-SymbolicName: testing.do.not.use.t
Import-Package: t
If I add the BND instruction
<Import-Package>*,org.eclipse.swt</Import-Package>
the [bundle] step gives this message:
[WARNING] Warning building bundle testing.do.not.use:t:bundle:0.0.1 :
Importing packages that are never refered to by any class on the
Bundle-Classpath[Jar:dot]
: [org.eclipse.swt]
But now the Eclipse build works.
(zip of the whole project sent to Stuart)
Hi Marshall,
this was an interesting one - I compiled the plug-in and used javap to
check the bytecode, and didn't see any reference to org.eclipse.swt!
this is because javac optimizes away the reference to SWT.ABORT,
which is declared as a "public static final int", and instead writes 512
into the bytecode.
so because the resulting classfile has no reference to org.eclipse.swt,
no import was generated (Bnd only sees the bytecode, not the source)
- basically, the bundle doesn't need this package during runtime.
Interesting - I confirmed that if I replace my test with something that
Java won't optimize away, BND includes the import.
however, it looks like Eclipse/PDE uses Import-Package to limit code
visibility at compile time, which means the Java compiler won't see the
SWT.ABORT field unless it's imported.
Perhaps it is simpler than this - I had thought that the Eclipse PDE
sets up a classpath consisting of the "Plug-in Dependencies" container
which, in turn, it computes from the manifest.mf - and since this file
makes no reference to the org.eclipse.swt package, that package or
bundle is not on the classpath, and can't be found.
also, just adding the import for org.eclipse.swt initially didn't work for
me because Eclipse/PDE associated this import with a bad bundle
that oddly didn't contain any classes (org.eclipse.swt_3.3.0.v3346.jar)
- once I removed this from my target platform it worked.
to sum up - for this particular case you'll have to explicitly add the
org.eclipse.swt package to your imports just to satisfy Eclipse/PDE
(you can safely ignore the BND warning)
of course, it does mean your bundle has an additional import that it
strictly doesn't need which is unfortunate (it's just there for Eclipse)
you might want to try my modified maven eclipse goal which comes
with Pax-Construct - just add the following repository to the example:
<pluginRepositories>
<pluginRepository>
<id>ops4j-repository</id>
<url>http://repository.ops4j.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
and run the following command instead of eclipse:eclipse:
mvn clean install org.ops4j:maven-pax-plugin:0.6.4:eclipse
(with a Pax-Construct project you can just use pax:eclipse)
this modified eclipse goal also adds maven dependencies as
required libraries, which means PDE sees the same compile
classpath as Maven and so avoids the unnecessary import
I tried this and found it added some of the maven dependencies and not
others (in particular, it missed the ones belonging to my project). I
traced this to my using <scope>compile</scope>. When I changed these to
<scope>provided</scope> the pax:eclipse added them to the referenced
library list, and Eclipse could compile the plugin.
I've read the section on scopes in
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
a few times, but confess to not really understanding what "compile" and
"provided" mean, and when I need to have one or the other. This page
says "provided" is like "compile", but you expect the JDK or container
to provide it. Even so, it seems maven's [compile] hooks up "provided"
things in the classpath it uses. What is the implication of expecting
"the JDK or container to provide it"?
It also says, for "provided" that "it is not transitive", but in the
next paragraph, it shows "provided" as being transitive for all scopes
(in the referenced POM) except test. This seems contradictory?
Any clarity / enlightenment ( ;-) ) you can bring here would be
appreciated. (I know it's a maven thing, and maybe a bit off topic).
-Marshall
HTH
ps. if all else fails, you could try IDEA or NetBeans ;)
Thanks for helping get to the bottom of this.
-Marshall
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]