ben-manes / caffeine

A high performance caching library for Java
Apache License 2.0
15.62k stars 1.58k forks source link

Dependency in tracing-async #22

Closed GenghisChen closed 9 years ago

GenghisChen commented 9 years ago

When switching to v1.3.0 the exception below is thrown; this is resolved only if tracing-async is added as a dependency to the project.

Caused by: java.lang.ClassNotFoundException: com.github.benmanes.caffeine.cache.tracing.Tracer
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1313) ~[catalina.jar:8.0.24]
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1164) ~[catalina.jar:8.0.24]
    at com.github.benmanes.caffeine.cache.LocalCache.tracer(LocalCache.java:64) ~[caffeine-1.3.0.jar:?]
    at com.github.benmanes.caffeine.cache.BoundedLocalCache.<init>(BoundedLocalCache.java:140) ~[caffeine-1.3.0.jar:?]
ben-manes commented 9 years ago

tracing-api should be added, but automatically due to being a maven dependency. Previously the api classes were accidentally bundled into the jar by the OSGi bnd tool.

If that doesn't work can you provide me a sample project to investigate with?

michaelhixson commented 9 years ago

I get the same thing. It's a runtime error; the project builds fine. Was tracing-api always <scope>compile</scope>?

Edit: Here's a pom.xml and Java source file that reproduces the error for me. I can't figure out why this happens... the caffeine poms look fine.

At /pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>caffeine-tracing-test</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>com.github.ben-manes.caffeine</groupId>
      <artifactId>caffeine</artifactId>
      <version>1.3.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.2</version>
        <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

At /src/main/java/Main.java:

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;

public class Main {
  public static void main(String[] args) {
    LoadingCache<String, Integer> cache =
        Caffeine.newBuilder().build(String::length);
    System.out.println(cache.get("hey"));
  }
}

Output:

Exception in thread "main" java.lang.NoClassDefFoundError: com/github/benmanes/caffeine/cache/tracing/Tracer
    at com.github.benmanes.caffeine.cache.LocalCache.tracer(LocalCache.java:64)
    at com.github.benmanes.caffeine.cache.UnboundedLocalCache.<init>(UnboundedLocalCache.java:71)
    at com.github.benmanes.caffeine.cache.UnboundedLocalCache$UnboundedLocalManualCache.<init>(UnboundedLocalCache.java:769)
    at com.github.benmanes.caffeine.cache.UnboundedLocalCache$UnboundedLocalLoadingCache.<init>(UnboundedLocalCache.java:822)
    at com.github.benmanes.caffeine.cache.Caffeine.build(Caffeine.java:841)
    at Main.main(Main.java:6) <5 internal calls>
Caused by: java.lang.ClassNotFoundException: com.github.benmanes.caffeine.cache.tracing.Tracer
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 11 more

IntelliJ seems convinced tracing-api:1.3.0 does not exist. Running it via mvn exec:java -Dexec.mainClass="Main" gives me a similar error.

ben-manes commented 9 years ago

Sorry I missed this comment, or I would have replied sooner.

I wonder if this might be because Gradle generates the pom with tracing-api in both compile scope and test scope. Perhaps that's messing it up?

I'll experiment with this on my way home (Caltrain), using Maven as a baseline. I'll make a new release if we can figure this out.

michaelhixson commented 9 years ago

Yeah that's it. 1.2.0 had <scope>test</code> before <scope>compile</code>. 1.3.0 has them in reverse order. ~Apparently Maven uses the last defined scope in that situation.~ or maybe not. Not sure what Maven is doing there.

ben-manes commented 9 years ago

That's a weird convention. I checked mvn dependency:tree with your example and it shows that its not coming in.

I think the only reason the test is used is due to a handy place to stash a reusable utility class, so I can probably fix that another way. I'm not sure how to prioritize the pom dependency order.

ben-manes commented 9 years ago

Yeah if I hack the pom in the .m2/repository I see that it can resolve iff the scope test is before compile. So Maven takes the last one defined, probably by abusing a HashMap.

ben-manes commented 9 years ago

I'll release this tonight as 1.3.1. Thanks!

ben-manes commented 9 years ago

Released. I checked all the poms in the staging repository and they all looked good. The jars should sync to central within the next two hours.

ben-manes commented 8 years ago

FYi,

Release v2 which no longer includes the tracing packages. A new eviction policy was chosen so capturing traces is no useful enough to be part of the API.