Base java classes still in the classpath during maven android build

两盒软妹~` 提交于 2020-01-11 12:51:17

问题


I'm having a rather strange problem caused by both the facts that the android java implementation differs from the sun java implementation and that the base java classes are still included in the classpath (all the way at the end) during a maven build of an android project. I think the solution is to not have the java classes on the classpath, but I can't seem to find a way to do this.

Basically, there is a class called AbstractExecutorService in java.util.concurrent (in both android and java). The java class contains a couple methods called newTaskFor which I'd like to use in android, but the android implementation doesn't have them. No problem, I'll just implement them (with a few changes such as using Future instead of RunnableFuture). This works fine in ant (the build tool we are migrating away from).

The problem is that when maven tries to compile my class (which extends AbstractExecutorService), instead of just adding my methods to the android implementation when it doesn't find them, it continues down the classpath, finds the java methods and complains that the return types don't match. Ideally I don't think the java classes should even be available during an android build, since all they can do is cause you to think you can run methods which you really can't, but currently you can run all sorts of java methods not available in android and it will compile fine (in maven).

Does anyone have any suggestions or solutions for this? Anyone run into something similar?



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

Note: ExecutionService is the class which extends AbstractExecutorService. However, I want it to ONLY extend the android version and not the base java version. I even tried inserting stub methods of the newTaskFor's into the android version of AbstractExecutorService (in the thought that the compiler should then assume I am overriding those methods rather than the base java ones - although I should note that there is no @Override in the code) but it still didn't work.

No one asked for them but here are my method declarations:

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

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

My current theory is that it has something to do with the template types but I'm not really sure how to go about proving or fixing that.

Edit 6/30: I should also note that this is not new code. It is over a year old and has been compiling perfectly using ant since then. It has been a part of numerous stable releases. We are now in the process of migrating our build process to maven and thus I am trying to get this package set up to build properly.


回答1:


The problem is that Maven automatically has the Oracle JDK on the classpath and that the Android jar provides alternate implementations of these and they sometimes differ. At this stage I do not know if the Maven Compiler Plugin can be told to remove the JDK from its classpath and just use the dependencies on the classpath. That would imho solve the issue.

Please create an issue in the Android Maven Plugin issue tracker and potentially investigate by asking on the Maven user or dev list.



来源:https://stackoverflow.com/questions/11250352/base-java-classes-still-in-the-classpath-during-maven-android-build

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!