On 12/02/2008, Marshall Schor <[EMAIL PROTECTED]> wrote:
>
> Stuart McCulloch wrote:
> > 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.


that's correct - but as well as deciding the "Plug-in Dependencies"
from the manifest, PDE also uses the Import-Package to decide
which packages are visible from that plug-in (though as you say,
in this case the missing import meant the plug-in wasn't added).

> 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.


correct - the logic at the moment is to add "test" and "provided"
dependencies as "Required Libraries" just in case Eclipse/PDE
doesn't add them as "Plug-in Dependencies".

this often happens with test dependencies, because the bundle
manifest doesn't usually contain the test imports, which means
that without this logic tests would fail to compile in Eclipse.

the reason I don't add "compile" or "runtime" dependencies is
because we typically use those when embedding code inside
bundles, in which case the pax plugin extracts the embedded
jars/folders to a local directory and adds them to the classpath.

however, I guess there's no harm in also adding the original
dependencies to the Eclipse classpath - I'll look into this for
the next release, if you think it would be useful.

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"?


here's how I typically use scopes when building bundles in Maven:

 "compile" - contains classes/resources that I want to embed
                  because my code needs them to load and I don't
                  expect them to be provided by another bundle.

 "runtime" - contains classes/resources that I want to embed
                 because my code might need them during runtime
                 (via reflection, etc.) and I don't expect them to be
                 provided by another bundle

 "provided" - contains classes/resources that I expect to be
                  provided by another bundle or the framework

 "test"       - contains classes/resources used in any unit or
                  integration tests (ie. not needed to load/run the
                  bundle - just needed to test with)

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?


yes, I really dislike that table - here's how it works in practice:

   A
    |   "compile"
   B                       classpath:  B, A
    |   "provided"
   C                       classpath:  C, B, A
    |   "provided"
   D                       classpath:  D, C

any dependencies of a "provided" dependency are treated as
if they were also "provided" in later projects - so A is treated
as a "provided" dependency in C, which then means it doesn't
appear in D because "provided" dependencies aren't transitive.

I think the table should really show '-' for 'provided x provided'

just to make things a bit more confusing, you can also mark
dependencies as "optional" which means they are excluded
by default from other projects depending on your project.

I always mark my "compile" and "runtime" dependencies as
optional, because I expect to embed them inside the bundle
and don't want them exposed to projects depending on my
bundle (saves downloading dependencies you won't use).

for example, when I want to use ASM inside a bundle, I'd add:

    <dependency>
      <groupId>asm</groupId>
      <artifactId>asm</artifactId>
      <version>2.2.3</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>

and set the Embed-Dependency instruction to embed/inline it.

  Any clarity / enlightenment ( ;-) ) you can bring here would be
> appreciated. (I know it's a maven thing, and maybe a bit off topic).


no problem - I think other Felix users will find this thread interesting

-- 
Cheers, Stuart

Reply via email to