Имеет ли LanguageTool Java API «бесполезные» зависимости? - PullRequest
0 голосов
/ 11 октября 2019

Я хочу использовать API Java LanguageTool для проверки орфографии, поэтому я добавляю его зависимость в мой pom.xml:

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

По какой-то причине он загружает 40 МБ jar зависимостей, которыевыглядит подозрительноВот снимок экрана со всеми из них:

enter image description here

Но если мы перейдем к центральный репозиторий maven , его .jarтолько 4,7 МБ .

После этого я заметил scala-compiler.jar, что составляет около 20 МБ , и я попытался исключить его:

<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 использует некоторые из них. Но как насчет неиспользованных? Используется ли он случайно, но в моем коде не используется какой-либо их класс, поэтому я избегаю получения ClassNotFoundException?

У меня вопрос, почему он загружает неиспользуемые зависимости. Есть ли способ узнать, какие из них бесполезны, чтобы я мог исключить их?

Чтобы убедиться, что они могут рассматриваться как «бесполезные», я даже строю свой jar (+ с зависимостями), и этоКажется, что программа работает без проблем. У меня есть только один класс с фрагментом кода выше. Это целое 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>

1 Ответ

0 голосов
/ 11 октября 2019

Позвольте мне попытаться ответить на этот вопрос более широко:

Maven строит список всех зависимостей, проходя транзитивно через дерево зависимостей, собирая каждую зависимость и затем осуществляя посредничество в зависимости (если вы найдете более одной версии)артефакта).

Это грубый способ сбора зависимостей, который более или менее гарантирует, что у вас есть все, что вам нужно, но часто у вас гораздо больше.

Почему это так?

Прежде всего, во время выполнения вы обычно вызываете только подмножество определенных классов, поэтому может легко случиться так, что некоторые части приложения (например, некоторые зависимости) никогда не будут затронуты. Во многих случаях было бы даже возможно статически доказать, что определенная зависимость никогда не может быть вызвана через нормальные цепочки, потому что, например, вы используете только один класс A зависимости a.jar, а a.jar зависит от b.jar, ноон нужен только для вещей, не связанных с A.

Но: существуют различные способы, которыми может потребоваться jar во время выполнения, которые трудно обнаружить. Это включает в себя различные типы внедрения зависимостей, особенно на сервере приложений.

...