1

I have three OSGI projects:

ProjectA (has dependency to ProjectB <scope>provided</scope>) has a class with the code

...
ClassB b=new ClassB();

ProjectB (has dependency to ProjectC <scope>provided</scope>) has the following class:

public class ClassB extends AbstractClassC{
...
}

ProjectC has the following class:

public abstract class AbstractClassC{
}

ProjectB and ProjectC export all necessary packages.

In order:

  1. I compile ProjectC - ok.
  2. I compile ProjectB - ok.
  3. I compile ProjectA - throws AbstractClassC not found.

When I add in ProjectA dependency to ProjectC everything compiles without a problem. Why does this happen? As I understand ProjectA must be compiled with only one dependency to ProjectB. Am I wrong?

I've checked several times AbstractClassC is not used in ProjectA and not imported.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186

1 Answers1

3

First of all, you can't make an instance of ClassB unless you know what to do with AbstractClassC, so that code won't compile without the reference.

The main problem you're having, though, is that <scope>provided</scope> is not transitive:

  • provided - This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.

Why are you using provided for classes you've written yourself? Just use compile, it will fix your issue. Alternatively, you could add the ProjectC dependency to ProjectA.

durron597
  • 31,968
  • 17
  • 99
  • 158
  • Thank you for your time. You marked the `is not transitive` as very important. But I can't understand what it means. Besides, with runtime I have no problem as it is osgi and all necessary bundles I add. I've always done this way and never had a problem. – Pavel_K Jul 14 '15 at 14:41
  • @JimJim2000 What is your first language (human, not programming)? – durron597 Jul 14 '15 at 14:43
  • I am native speaker of Russian. I've translated the "transitive" but I can't understand what it means in compilation `to be transitive`. – Pavel_K Jul 14 '15 at 14:45
  • @JimJim2000 ProjectB depends on ProjectC. If this dependency **is transitive**, then when you declare a dependency on ProjectB in ProjectA, it will **also add ProjectC to your classpath**. If it **is not transitive**, then it will **not add ProjectC to your classpath**. Also, I recommend using [Russian Language Stack Exchange](http://ru.stackoverflow.com/) – durron597 Jul 14 '15 at 14:49
  • From this http://stackoverflow.com/a/25777709/5057736 as I understand if I set scope to compile then ProjectA will include code from ProjectB. And I don't want it, as it is osgi. – Pavel_K Jul 14 '15 at 14:50
  • I think that your answer is half-right. You are right that the problem is that provided scope is not transitive, but you advise to use compile scope. I think I should use provided scope and add the ProjectC to ProjectA as dependency (scope=provided). Anyway, thank you for your time! – Pavel_K Jul 14 '15 at 15:30
  • @JimJim2000 I added a sentence about that; I didn't suggest it because it sort of defeats the purpose of Maven - the whole point of Maven is that you don't have to add transitive dependencies manually. However, it's possible I don't understand the OSGi part of the problem well enough. Anyway, if I've helped you, don't forget to accept (green checkmark) my answer! – durron597 Jul 14 '15 at 15:38