LanguageTool Java API 是否有 "useless" 依赖项?

Does LanguageTool Java API have "useless" dependencies?

我想使用 LanguageTool's Java API 进行拼写检查,因此我将其依赖项添加到我的 pom.xml:

<dependency>
  <groupId>org.languagetool</groupId>
  <artifactId>language-en</artifactId>
  <version>4.7</version>
</dependency>

出于某种原因,它下载了 40MB jar 看起来可疑的依赖项。这是所有这些的屏幕截图:

但是如果我们去maven central repository,它的.jar只有4.7MB.

之后我注意到 scala-compiler.jar 大约 20MB,我试图排除它:

<exclusion>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-compiler</artifactId>
</exclusion>

然后我 运行 我的 main 和一切 运行 都很好:

public static void main(String[] args) throws IOException {
    JLanguageTool lang = new JLanguageTool(new AmericanEnglish());
    List<RuleMatch> matches = lang.check("This is a speling errorr.");
    for (RuleMatch match : matches)
    {
        System.out.println(match.getSuggestedReplacements());
    }
}

所以我花了一些时间开始排除越来越多的依赖项,其中一些我得到了 ClassNotFoundException,这很好,因为如果 language-tool 使用其中一些是有意义的。但是那些没用过的呢?有没有机会使用,但我的代码不使用其中的任何 class,所以我避免得到 ClassNotFoundException?

我的问题是为什么它会下载未使用的依赖项。有没有办法找出其中哪些是无用的,以便我可以排除它们?

为了确保它们可以被视为 "useless" 我什至构建了我的 jar(+ 依赖项)并且程序似乎运行没有问题。我只有一个 class 里面有上面的代码片段。这是整个pom.xml:

<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>test.org</groupId>
    <artifactId>anothertest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>test.Re</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>

                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>package</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.languagetool</groupId>
            <artifactId>language-en</artifactId>
            <version>4.7</version>
            <exclusions>
                <exclusion>
                    <groupId>edu.berkeley.nlp</groupId>
                    <artifactId>berkeleylm</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.typesafe.akka</groupId>
                    <artifactId>akka-actor_2.11</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.scala-lang</groupId>
                    <artifactId>scala-compiler</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.scala-lang</groupId>
                    <artifactId>scala-reflect</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
                    <artifactId>jackson-jaxrs-base</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
                    <artifactId>jackson-jaxrs-json-provider</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.module</groupId>
                    <artifactId>jackson-module-jaxb-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.lucene</groupId>
                    <artifactId>lucene-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.glassfish.jaxb</groupId>
                    <artifactId>jaxb-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.glassfish.jaxb</groupId>
                    <artifactId>jaxb-runtime</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.glassfish.jaxb</groupId>
                    <artifactId>txw2</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>net.java.dev.jna</groupId>
                    <artifactId>jna</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.optimaize.languagedetector</groupId>
                    <artifactId>language-detector</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.esotericsoftware.kryo</groupId>
                    <artifactId>kryo</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>

让我尝试更笼统地回答这个问题:

Maven 通过遍历依赖关系树构建所有依赖关系的列表,收集每个依赖关系,然后进行依赖关系调解(如果您发现工件的多个版本)。

这是一种粗略的收集依赖关系的方法,它或多或少地保证了您拥有所需的一切——但通常您拥有的更多。

这是为什么?

首先,在运行时,您通常只调用已定义的 classes 的子集,因此很容易发生应用程序的某些部分(如某些依赖项)从未被触及的情况。在许多情况下,甚至可以静态地证明某个依赖项永远不能通过正常链调用,因为例如你只使用一个 class A 的依赖项 a.jar,而 a.jar 依赖于 b.jar 但只需要它用于与 A 无关的事情。

但是:在运行时,jar 可能 有多种方式是必需的,但很难检测到。这包括不同类型的依赖注入,尤其是在应用程序服务器上。