我遇到了一个相当奇怪的问题,原因是 android java 实现与 sun java 实现不同,并且在 maven 构建期间,基本 java 类仍然包含在类路径中(一直到最后)安卓项目。我认为解决方案是在类路径上没有 java 类,但我似乎无法找到一种方法来做到这一点。
基本上,在 java.util.concurrent 中有一个名为 AbstractExecutorService 的类(在 android 和 java 中)。java 类包含几个名为 newTaskFor 的方法,我想在 android 中使用它们,但 android 实现没有它们。没问题,我将实现它们(进行一些更改,例如使用 Future 而不是 RunnableFuture)。这在 ant(我们正在迁移的构建工具)中运行良好。
问题是,当 maven 尝试编译我的类(它扩展了 AbstractExecutorService),而不是在找不到它们时将我的方法添加到 android 实现中,它继续沿着类路径,找到 java 方法并抱怨返回类型不匹配。理想情况下,我认为 java 类甚至不应该在 android 构建期间可用,因为它们所能做的就是让你认为你可以运行你真的不能运行的方法,但目前你可以运行各种 java 方法而不是在 android 中可用,它会编译得很好(在 maven 中)。
有没有人对此有任何建议或解决方案?有人遇到类似的事情吗?
编辑:这是 pom 的相关部分(省略了存储库等):
<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:这是我得到的编译错误。
[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的存根方法插入到AbstractExecutorService的android版本中(认为编译器应该假设我正在覆盖这些方法而不是基本的java方法 - 尽管我应该注意到代码中没有@Override ) 但它仍然没有工作。
没有人要求他们,但这是我的方法声明:
protected <T> Future<T> newTaskFor(Runnable runnable, T value)
{
//stuff
}
protected <T> Future<T> newTaskFor(Callable<T> callable)
{
//stuff
{
我目前的理论是它与模板类型有关,但我不确定如何去证明或修复它。
编辑 6/30:我还应该注意这不是新代码。它已有一年多的历史,从那时起一直使用 ant 完美编译。它已成为众多稳定版本的一部分。我们现在正在将我们的构建过程迁移到 maven,因此我正在尝试设置这个包以正确构建。