Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main API tries and fails to load an optional dependency #113

Closed
jvasileff opened this issue Nov 4, 2014 · 24 comments
Closed

Main API tries and fails to load an optional dependency #113

jvasileff opened this issue Nov 4, 2014 · 24 comments
Assignees
Milestone

Comments

@jvasileff
Copy link
Member

Running a basic hello-world program with:

module com.example.helloworld "1.0.0" {
    import "com.google.guava:guava" "18.0";
}

using:

java -cp $(ceylon classpath --rep aether com.example.helloworld/1.0.0) \
    com.redhat.ceylon.compiler.java.runtime.Main \
    com.example.helloworld/1.0.0 \
    com.example.helloworld.run_

fails with:

Exception in thread "main" java.lang.RuntimeException: com.redhat.ceylon.compiler.java.runtime.Main$ClassPath$ModuleNotFoundException: Module com.google.code.findbugs:jsr305/1.3.9 not found
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:546)
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:553)
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:553)
    at com.redhat.ceylon.compiler.java.runtime.Main.setupMetamodel(Main.java:528)
    at com.redhat.ceylon.compiler.java.runtime.Main.runModule(Main.java:474)
    at com.redhat.ceylon.compiler.java.runtime.Main.main(Main.java:580)
Caused by: com.redhat.ceylon.compiler.java.runtime.Main$ClassPath$ModuleNotFoundException: Module com.google.code.findbugs:jsr305/1.3.9 not found
    at com.redhat.ceylon.compiler.java.runtime.Main$ClassPath.loadModule(Main.java:297)
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:542)
    ... 5 more

The jsr305 module is an optional dependency of Guava - see https://repo1.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0.pom

ceylon classpath ... lists guava-18.0.jar, but, as expected, not jsr305.jar.

One interesting item: I have no idea where Main is getting the version number in jsr305/1.3.9. Guava's pom.xml does not specify a version.

@quintesse
Copy link
Member

@quintesse
Copy link
Member

Btw @FroMage , as you can see it's not during compilation but at runtime that this error occurs. It seems it's trying to register the metamodel for the optional module which isn't available. At least that's my guess.

@quintesse
Copy link
Member

NB: should the ceylon classpath tool have an --include-optionals flag or something? Or perhaps the default should be to include them (better safe than sorry) and have an --exclude-optionals?

@jvasileff
Copy link
Member Author

Oh, that makes sense. And, it's not listed as optional in the parent pom; maybe that has something to do with it.

On a related note, it looks like Main makes a network connection to download poms if necessary. I guess that makes sense, especially here, but it's not something I'd want on a production server.

@quintesse
Copy link
Member

but it's not something I'd want on a production server.

Try setting the offline mode. (I'm not really sure if the Main API makes that easy to do, @FroMage ?)

@FroMage
Copy link
Member

FroMage commented Nov 5, 2014

In theory the Main API will not do network lookups, but that's not true for Maven, because we haven't found the flag in aether to make it not do remote lookups.

As for including the optional jars by default in classpath, I guess that's a good idea, but would it fix the problem here?

@quintesse
Copy link
Member

because we haven't found the flag in aether to make it not do remote lookups.

That was already implemented some time ago, it should work.

@quintesse
Copy link
Member

(the thing we don't support yet are timeouts because the Aether stuff doesn't have an API for that)

@FroMage
Copy link
Member

FroMage commented Nov 5, 2014

Not for this IIRC.

@FroMage
Copy link
Member

FroMage commented Nov 5, 2014

See #87 (comment)

@quintesse
Copy link
Member

Are you sure? I remember this was tested when we added it to the resolver:

ConfigurableMavenResolverSystem factory = Resolvers.use(ConfigurableMavenResolverSystem.class, classLoader).workOffline(offline);

Wasn't the problem with that issue that you can't just read the information from the POM without it trying to download the artifacts (when offline=false)

@FroMage
Copy link
Member

FroMage commented Nov 5, 2014

Yes, as the comments say, there's no way to make aether read just the pom file without resolving. I suppose that if I set it to offline it will not hit the net, though, so it should stick to the local cache, which should work.

@FroMage FroMage added this to the 1.1.5 milestone Jan 26, 2015
@FroMage FroMage added the BUG label Jan 26, 2015
@alesj
Copy link
Member

alesj commented Feb 4, 2015

I've added this test and it passes:

@Test
public void testOptionalDependency() throws Throwable {
    Repository repository = AetherRepository.createRepository(log, false, 60000);
    RepositoryManager manager = new SimpleRepositoryManager(repository, log);
    ArtifactResult result = manager.getArtifactResult("com.google.guava:guava", "18.0");
    Assert.assertNotNull(result);
    Assert.assertEquals(result.name(), "com.google.guava:guava");
    File artifact = result.artifact();
    boolean exists = false;
    try {
        Assert.assertNotNull(artifact);
        Assert.assertTrue(artifact.exists());
        exists = true;
        Assert.assertTrue(result.dependencies() == null || result.dependencies().isEmpty());
    } finally {
        if (exists) {
            Assert.assertTrue(artifact.delete()); // delete this one
        }
    }
}

quintesse added a commit that referenced this issue Feb 4, 2015
@quintesse
Copy link
Member

@alesj This wasn't so much about the CMR not finding the artifacts but about AetherUtils returning the wrong information about them.

@jvasileff This seems to work now for me. Could you confirm so we can close this?

@jvasileff
Copy link
Member Author

@quintesse great, that helps! Indeed, java -cp ... Main ... works for me now.

But, I'm afraid there is more to this. The following still fail:

Running without the Main api:

$ ceylonDev run simple --rep aether
ceylon run: Could not find module: com.google.guava/guava/18.0 (invalid
version?)

Running without the Main api, without guava, but with import "com.google.code.findbugs:jsr305" "1.3.9";

$ ceylonDev run simple --rep aether
ceylon run: Could not find module: com.google.code.findbugs/jsr305/1.3.9
(invalid version?)

Running with the Main api, with or without guava, but with import "com.google.code.findbugs:jsr305" "1.3.9";

$ java -cp $(ceylonDev classpath --rep aether simple/1.0.0) com.redhat.ceylon.compiler.java.runtime.Main simple/1.0.0 simple.run_
Exception in thread "main" java.lang.RuntimeException: com.redhat.ceylon.compiler.java.runtime.Main$ClassPath$ModuleNotFoundException: Module com.google.code.findbugs:jsr305/1.3.9 not found
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:556)
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:566)
    at com.redhat.ceylon.compiler.java.runtime.Main.setupMetamodel(Main.java:538)
    at com.redhat.ceylon.compiler.java.runtime.Main.runModule(Main.java:484)
    at com.redhat.ceylon.compiler.java.runtime.Main.main(Main.java:593)
Caused by: com.redhat.ceylon.compiler.java.runtime.Main$ClassPath$ModuleNotFoundException: Module com.google.code.findbugs:jsr305/1.3.9 not found
    at com.redhat.ceylon.compiler.java.runtime.Main$ClassPath.loadModule(Main.java:304)
    at com.redhat.ceylon.compiler.java.runtime.Main.registerInMetamodel(Main.java:552)
    ... 4 more

Note: ceylonDev classpath --rep aether simple/1.0.0 does include the findbugs jar when imported in module.ceylon.

So, I suspect there are two issues:

  • ceylon run appears to still want to load the optional dependency
  • The module loader cannot make sense of the findbugs jar, since it is missing pom.xml. (updated - fixed grep cmd)
$ unzip -l /Users/jvasileff/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar | grep pom
$

For reference, my module.ceylon file:

module simple "1.0.0" {
  // comment/uncomment one or both of these: 
  import "com.google.guava:guava" "18.0";
  import "com.google.code.findbugs:jsr305" "1.3.9";
}

@quintesse
Copy link
Member

@jvasileff you're using a wrong command line syntax. Everything after the module name for "ceylon run" are supposed to be arguments for the program you're running. So the --rep aether has to come before the module name. (But after the word "run")
(Edit: fixed mistake in text)

@jvasileff
Copy link
Member Author

Oops.

So ceylon run looks like it works in all cases. The only remaining issue seems to be the Main API w/findbugs imported, which I'm guessing would also affect the Tool Provider API, although I haven't tested that, yet.

@quintesse
Copy link
Member

I tried it with both imported and it still seemed to work fine. What problem are you seeing?

@quintesse
Copy link
Member

Ah no, I have reproduced it

quintesse added a commit to ceylon/ceylon-runtime that referenced this issue Feb 4, 2015
@jvasileff
Copy link
Member Author

Not a super controlled test, but it looks like the tool provider API is indeed affected:

   [tomcat] Caused by: java.lang.RuntimeException: Missing module: com.google.code.findbugs:jsr305/1.3.9
   [tomcat]     at com.redhat.ceylon.compiler.java.runtime.tools.impl.JavaRunnerImpl.loadModule(JavaRunnerImpl.java:212)
   [tomcat]     at com.redhat.ceylon.compiler.java.runtime.tools.impl.JavaRunnerImpl.loadModule(JavaRunnerImpl.java:224)
   [tomcat]     at com.redhat.ceylon.compiler.java.runtime.tools.impl.JavaRunnerImpl.<init>(JavaRunnerImpl.java:65)
   [tomcat]     at com.redhat.ceylon.compiler.java.runtime.tools.CeylonToolProvider.getRunner(CeylonToolProvider.java:27)
   [tomcat]     at com.redhat.ceylon.war.WarInitializer.initialize(WarInitializer.java:85)

@quintesse
Copy link
Member

Well it's indeed because the findbugs jar does not have any meta data at all.

@jvasileff
Copy link
Member Author

Incidentally, compiling with jsr305 fails if you also need import javax.annotation "7";. jsr305.jar includes some javax.annotation classes, but not the one that causes the compile error in my case, which is javax.annotation.PostConstruct.

source/.../Repository.ceylon:13: error: imported declaration not found: 'postConstruct'
    postConstruct
   ^
source/.../Repository.ceylon:38: error: function or value does not exist: 'postConstruct'
    postConstruct shared
   ^

@quintesse
Copy link
Member

Well to be honest @jvasileff I'd like to close this issue if you don't mind because I think the original problem is now fixed. Please open a new issue in ceylon.language for this new problem with dependencies that have no (useful) meta-data.

@jvasileff
Copy link
Member Author

@quintesse ok, done. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants