Вопрос по classpath, maven, android – Базовые классы Java все еще в пути к классам во время сборки Android Maven

0

У меня довольно странная проблема, вызванная тем фактом, что реализация Java для Android отличается от реализации Sun Java и что базовые Java-классы по-прежнему включены в classpath (полностью в конце) во время сборки maven Android-проект. Я думаю, что решение состоит в том, чтобы не иметь классов Java на пути к классам, но я, кажется, не могу найти способ сделать это.

В сущности, в java.util.concurrent есть класс AbstractExecutorService (как в Android, так и в Java). Класс java содержит пару методов, называемых newTaskFor, которые я хотел бы использовать в android, но у реализации android их нет. Нет проблем, я просто реализую их (с некоторыми изменениями, такими как использование Future вместо RunnableFuture). Это хорошо работает в муравье (инструмент сборки, от которого мы мигрируем).

Проблема в том, что когда maven пытается скомпилировать мой класс (который расширяет AbstractExecutorService), вместо того, чтобы просто добавлять мои методы в реализацию Android, когда он не находит их, он продолжает путь по классам, находит методы java и жалуется, что возвращаемый результат типы не совпадают. В идеале я не думаю, что java-классы должны быть доступны даже во время сборки Android, поскольку все, что они могут сделать, это заставить вас думать, что вы можете запускать методы, которые вы действительно не можете, но в настоящее время вы можете запускать все виды java-методов, не доступно в Android, и он будет компилироваться нормально (в Maven).

У кого-нибудь есть какие-либо предложения или решения для этого? Кто-нибудь сталкивался с чем-то подобным?



Edit: here is the relevant part of the pom (omitted repositories and such):

<dependencies>
    <dependency>
        <groupId>org.beanshell</groupId>
        <artifactId>bsh</artifactId>
        <version>2.0b5</version>
        <optional>true</optional>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
        <optional>true</optional>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.4</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.google.android</groupId>
        <artifactId>android-with-java</artifactId>
        <version>2.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.byteman</groupId>
        <artifactId>byteman-bmunit</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>bouncycastle</groupId>
        <artifactId>bcprov-jdk15</artifactId>
        <version>140</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <sourceDirectory>src</sourceDirectory>
    <resources>
        <resource>
            <directory>conf</directory>
            <includes>
                <include>*.xml</include>
            </includes>
            <excludes>
                <exclude>*-service.xml</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>${project.build.directory}/schema</directory>
        </resource>
        <resource>
           <directory>${project.basedir}</directory>
           <includes>
              <include>INSTALL.html</include>
              <include>LICENSE</include>
              <include>README</include>
           </includes>
        </resource>
        <resource>
          <directory>${project.basedir}/lib</directory>
          <includes>
             <include>licenses/thirdparty*</include>
          </includes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <excludes>
                    <exclude>stuff/stuff/util/JUnitXMLReporter.java</exclude>
                </excludes>
            </configuration>
        </plugin>
       <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>build-helper-maven-plugin</artifactId>
          <version>1.7</version>
          <executions>
             <execution>
                <id>add-source</id>
                <phase>validate</phase>
                <goals>
                   <goal>add-source</goal>
                </goals>
                <configuration>
                   <sources>
                      <source>target/generated-sources</source>
                   </sources>
                </configuration>
             </execution>
             <execution>
                <id>add-test-source</id>
                <phase>validate</phase>
                <goals>
                   <goal>add-test-source</goal>
                </goals>
             </execution>
          </executions>
       </plugin>
       <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <phase>process-resources</phase>
                  <configuration>
                    <tasks>
                        <echo>Precompiling magic ids and protocol ids</echo>    
                        <xslt in="conf/stuff.xml" out="target/generated-sources/stuff/stuff/ClassMagicEncoding.java"
                            style="conf/stuff.xslt">
                            <param name="type" expression="Magic"/>
                        </xslt>
                        <xslt in="conf/stuff.xml" out="target/generated-sources/stuff/stuff/ClassProtocolEncoding.java"
                            style="conf/stuff.xslt">
                            <param name="type" expression="Protocol"/>
                        </xslt>
                    </tasks>
                  </configuration>
                </execution>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <property name="compile_classpath" refid="maven.compile.classpath"/>
                            <property name="plugin_classpath" refid="maven.plugin.classpath"/>
                            <delete dir="${project.build.directory}/schema" failonerror="false"/>
                            <mkdir dir="${project.build.directory}/schema"/>
                            <java classname="stuff.stuff.util.XMLSchemaGenerator">
                                <classpath>
                                    <pathelement path="${compile_classpath}"/>
                                    <pathelement path="${plugin_classpath}"/>
                                </classpath>
                                <arg line="-o ${project.build.directory}/schema"/>
                            </java>
                        </tasks>
                    </configuration>
                </execution>
            </executions>

            <configuration>
                <!-- prints the classpath to ensure correct jars are available -->
                <tasks>
                            <property name="compile_classpath" refid="maven.compile.classpath"/>
                    <echo>rawr=${compile_classpath}</echo>
                    <echo>java.class.path=${java.class.path}</echo>
                    <echo>CLASSPATH=${env.CLASSPATH}</echo>
                </tasks>
            </configuration>

            <dependencies>
                <dependency>
                    <groupId>xalan</groupId>
                    <artifactId>xalan</artifactId>
                    <version>2.7.1</version>
                </dependency>
                <dependency>
                    <groupId>xalan</groupId>
                    <artifactId>serializer</artifactId>
                    <version>2.7.1</version>
                </dependency>
                <dependency>
                    <groupId>ant</groupId>
                    <artifactId>ant-antlr</artifactId>
                    <version>1.6.5</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.ant</groupId>
                    <artifactId>ant-nodeps</artifactId>
                    <version>1.8.1</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Main-Class>stuff.stuff.Version</Main-Class>
                    <Implementation-Version>${project.version}</Implementation-Version>
                    <Export-Package>
                        schema;version=${project.version},
                        ${project.groupId}.*;version=${project.version}
                    </Export-Package>
                    <Bundle-RequiredExecutionEnvironment>J2SE-1.6</Bundle-RequiredExecutionEnvironment>
                </instructions>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.jayway.maven.plugins.android.generation2</groupId>
            <artifactId>android-maven-plugin</artifactId>
            <version>3.2.0</version>
            <extensions>true</extensions>
                <configuration>
                    <sdk>
                         <platform>8</platform>
                    </sdk>
                    <undeployBeforeDeploy>true</undeployBeforeDeploy>
                </configuration>
        </plugin>
    </plugins>
</build>





Edit2: Here is the compilation error I am getting.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project mystuff: Compilation failure: Compilation failure:
[ERROR] /home/stuff/stuff/ExecutionService.java:[775,28] <T>newTaskFor(java.lang.Runnable,T) in stuff.ExecutionService cannot override <T>newTaskFor(java.lang.Runnable,T) in java.util.concurrent.AbstractExecutorService; attempting to use incompatible return type
[ERROR] found   : java.util.concurrent.Future<T>
[ERROR] required: java.util.concurrent.RunnableFuture<T>
[ERROR] /home/stuff/ExecutionService.java:[791,28] <T>newTaskFor(java.util.concurrent.Callable<T>) in stuff.ExecutionService cannot override <T>newTaskFor(java.util.concurrent.Callable<T>) in java.util.concurrent.AbstractExecutorService; attempting to use incompatible return type
[ERROR] found   : java.util.concurrent.Future<T>
[ERROR] required: java.util.concurrent.RunnableFuture<T>
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project mystuff: Compilation failure

Примечание: ExecutionService - это класс, который расширяет AbstractExecutorService. Тем не менее, я хочу, чтобы он расширял только версию для Android, а не базовую версию Java. Я даже пытался вставить методы-заглушки newTaskFor в Android-версию AbstractExecutorService (полагая, что компилятор должен тогда предположить, что я переопределяю эти методы, а не базовые java - хотя я должен отметить, что @Override в код), но он все еще не работает.

Никто не просил их, но вот мои объявления методов:

protected <T> Future<T> newTaskFor(Runnable runnable, T value) 
{
//stuff
}

protected <T> Future<T> newTaskFor(Callable<T> callable) 
{
//stuff
{

Моя текущая теория заключается в том, что это как-то связано с типами шаблонов, но я не совсем уверен, как это доказать или исправить.

Edit 6/30: Я должен также отметить, что этоnot новый код Ему более года, и с тех пор он прекрасно компилируется с использованием ant. Это было частью многочисленных стабильных релизов. Сейчас мы находимся в процессе миграции нашего процесса сборки на maven, и поэтому я пытаюсь настроить этот пакет для правильной сборки.

Да, готово. Также добавлена некоторая дополнительная информация. matt5784
Вы можете показать файл POM? khmarbaise
Можете ли вы также подробно описать ошибку компиляции? yorkw
Я еще раз посмотрел на ваш вопрос, что-то не совсем подходит в вашем подходе. Ваш модифицированный android.jar используется только во время компиляции, исполняемый framework.jar, установленный на фактическом устройстве / эмуляторе, никогда не получит его (если вы не измените его каким-либо образом). Мне интересно, как вы сделали это с Ant, пробовали ли вы запустить Ant-build apk на произвольном устройстве (или эмуляторе)? Я не думаю, что это сработает, даже если вы следите за ответом Манфреда, чтобы решить проблему с classpath (которая может позволить вам пройти компиляцию). yorkw
Добавлен. Я понял, что забыл отметить, что это по сути (во всех смыслах и целях) проект библиотеки. На самом деле не работает на Android, а просто предоставляет приложения для приложений. matt5784

Ваш Ответ

1   ответ
1

Проблема заключается в том, что Maven автоматически размещает Oracle JDK на пути к классам, и что Jar-файл Android предоставляет альтернативные варианты реализации, и они иногда отличаются. На данном этапе я не знаю, можно ли сказать плагину Maven Compiler удалить JDK из его пути к классам и просто использовать зависимости от пути к классам. Это имхо решит проблему.

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

Можете ли вы создать проблему на трекере проблем ... Я спрошу об этом в списке разработчиков Maven.
Это правда - однако, как я уже сказал в своем комментарии ниже, я отредактировал android.jar с объявлениями методов, которые идентичны моим методам. Android.jar - это первый элемент пути к классам. Тем не менее, maven по-прежнему выбирает версии Java (последний элемент в пути к классам), когда пытается найти методы, которые реализуют мои методы. Есть идеи, почему это так? matt5784
Похоже, что (основываясь на моих исследованиях и тестировании) нет способа удалить базовую Java из classpath. По сути, это делает (без проблем) разработку Android невозможной с помощью Maven, так как вы никогда не можете быть уверены, какую версию он использует. Учитывая все проблемы, с которыми я столкнулся, я не уверен, как кто-то использует maven для сборок Android ... в любом случае, я собираюсь принять ваш ответ, так как решение этой проблемы, похоже, не является решением. matt5784
Я спросил об этом на странице групп Google android-maven-plugin немного назад. Ответивший сказал мне, как исправить это в затмении, но когда я сказал ему: «Я не использую затмение, я бегу из терминала». он перестал отвечать. matt5784
Я спросил сейчас. Посмотрим, что из этого получится.

Похожие вопросы