2011-08-16 7 views
4

Android Maven統合を使用してEclipseでプロジェクトを設定しましたが、一部のテストでRobolectricを設定しました。Maven surefireプラグインでRobolectricテストを実行しているときにClassNotFoundExceptionを取得しています

Eclipseでデプロイするとテストが正常に実行されます。しかし、Mavenの "インストール"目標(これは実際に私のローカルMavenリポジトリに必要なライブラリです)を使ってプロジェクトをビルドしようとすると、同じテストで失敗します。

testAll((package).MyTest) Time elapsed: 0.006 sec <<< ERROR! 
java.lang.RuntimeException: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for (package).R 
    at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:316) 
    at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:270) 
    at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:221) 
    at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:201) 
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59) 
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120) 
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103) 
    at org.apache.maven.surefire.Surefire.run(Surefire.java:169) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350) 
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021) 
Caused by: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for (package).R 
    at javassist.Loader.findClass(Loader.java:359) 
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.findClass(RobolectricClassLoader.java:60) 
    at javassist.Loader.loadClass(Loader.java:311) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.loadClass(RobolectricClassLoader.java:37) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:169) 
    at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:312) 
    ... 22 more 
Caused by: com.xtremelabs.robolectric.bytecode.IgnorableClassNotFoundException: msg because of javassist.NotFoundException: (package).R 
    at com.xtremelabs.robolectric.bytecode.AndroidTranslator.onLoad(AndroidTranslator.java:80) 
    at javassist.Loader.findClass(Loader.java:340) 
    ... 29 more 

(パッケージ)は、もちろん私のメインパッケージの名前です:

ログには、次のエラーが表示されます。

<dependencies> 
    <dependency> 
     <groupId>com.google.android</groupId> 
     <artifactId>android</artifactId> 
     <version>2.1.2</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.pivotallabs</groupId> 
     <artifactId>robolectric</artifactId> 
     <version>0.9.8</version> 
     <type>jar</type> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.hamcrest</groupId> 
     <artifactId>hamcrest-core</artifactId> 
     <version>1.2</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.8.2</version> 
     <scope>test</scope> 
    </dependency> 
    </dependencies> 

    <build> 
    <defaultGoal>package</defaultGoal> 
    <plugins> 
     <plugin> 
     <groupId>com.jayway.maven.plugins.android.generation2</groupId> 
     <artifactId>maven-android-plugin</artifactId> 
     <version>2.8.3</version> 
     <configuration> 
     <genDirectory>${project.basedir}/gen</genDirectory> 
      <androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile> 
      <assetsDirectory>${project.basedir}/assets</assetsDirectory> 
      <resourceDirectory>${project.basedir}/res</resourceDirectory> 
      <nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory> 
      <sdk> 
      <platform>7</platform> 
      </sdk> 
      <deleteConflictingFiles>true</deleteConflictingFiles> 
      <undeployBeforeDeploy>true</undeployBeforeDeploy> 
     </configuration> 
     <extensions>true</extensions> 
     </plugin> 

     <plugin> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>2.3.2</version> 
     <configuration> 
      <source>1.6</source> 
      <target>1.6</target> 
     </configuration> 
     </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-surefire-plugin</artifactId> 
     <version>2.6</version> 
     <configuration> 
      <excludes> 
       <exclude>**/Test*.java</exclude> 
      </excludes> 
     </configuration> 
    </plugin>  
    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-javadoc-plugin</artifactId> 
     <version>2.8</version> 
    </plugin> 
    </plugins> 
    </build> 

あなたが見ることができるように、私はMavenのAndroidのプラグインに「genDirectory」オプションを追加しようとしました:ここに私のPOMの関連するセクションです。しかし、役に立たない。

確かに、確かなプラグインを作るには何が欠けていますか?

さらにもう1つ:Rクラスは実際に自分のコードで参照されていません。

+0

「インストール」という目標は何を意味していますか? Eclipseには、アプリケーションを実行するための実行モードとデバッグモードがあります。インストールはAndroid SDKによって処理されます。 Maven/Robolectricコードからエラーが発生している場合は、それらをビルドパスに含めてください。 – Codeman

+0

"インストール"目標は、Maven特有のアクションです。ローカルMavenリポジトリにプロジェクトを追加します(このプロジェクトは実際にはライブラリです)。言い換えれば、これはEclipse実行サイクルから独立したものです。私は、この点を明確にするために質問を編集します。 –

+0

R.javaクラスはAndroidによってコンパイルされています。Androidプロジェクト外で参照する必要はありません。具体的には、アクティビティ参照なしで参照することはできません。 – Codeman

答えて

3

Robolectricを追加して初めてEclipseからテストを実行しようとしたときに同じ問題が発生しました。

私が問題を解決したのは、コマンドラインでmvn clean testでした。 それから、テストはEclipseでもOKでした。

そして、<packaging>apk</packaging>があなたのpom.xmlにあることを確認してください。

+0

残念ながら、それはうまくいきませんでした。問題がそれほど大きくない場合は、POMで編集できますか?たぶん私は何かが間違って設定されているかもしれません... –

+0

"これは実際にライブラリです"とは何を意味するのか分かりません。私は ' apk'を私のpomに持っています。私がそれを ' jar'と置き換えると、 "パッケージRは存在しません"と失敗します。 – altumano

+0

...もちろん、それはうまくいきました(私はMavenリポジトリをセットアップし、それが逆火するまで、使い方を少し便利にしたいと思っていました)。ありがとう! パッケージを "apk"に設定する情報を追加して、受け入れてアップヴォートすることができますか? –

4

私もこの問題を正確に受けました。

私はRobolectricSampleプロジェクトと私のプロジェクトとを慎重に比較しました。

私が驚いたことに、「mvn clean test」のコマンドラインを最初に実行しなかった場合、RobolectricSampleプロジェクトも動作しませんでした。

私はその違いを分析し、コマンドラインが "gen/xxx/R.java"を "target/classes/xxx/R"にもコンパイルしていることがわかりました。

これは成功の秘訣ですので、私は次のステップを実行しました: 1.プロジェクト - > Javaビルドを右クリックします。 2. "{project}/gen"の出力フォルダを "target/android-classes"の代わりに "target/class"に変更してください。

これは役に立ちます。

0

Robolectricテストをeclipseとコマンドラインの両方でmvn clean test経由で実行すると、同じ問題が発生しました。私。 java.lang.ClassNotFoundException私のR.classファイルが見つからないと不平を言った。私のプロジェクトはリソースを持たないAndroidライブラリなので、実際にはR.classファイルはありませんでした。

ダーティハックエラーを取り除くには、使用されていない単一の文字列で<project-home>/res/values/strings.xmlファイルを作成することです。その後、R.javaと対応するR.classが生成され、エラーはなくなります。

4

この問題を解決する唯一の方法は、偽のRを配置することでした。パッケージにjavaファイル:

public class R { 
     public static final class attr { 
     } 

     public static final class drawable { 
     } 

     public static final class id { 
     } 

     public static final class layout { 
     } 

     public static final class string { 
     } 
    } 

この以下の状況でのみ必要でなければなりません:

  1. MavenのライブラリプロジェクトRobolectric
  2. ユニットテストの依存
  3. R.java生成されていませんか、 Mavenクラスパスには見つかりませんでした。

注:R.javaをテストソースに配置して、デプロイされないようにすることができます。これは実際に作成されたリソースに干渉しません。

+0

これは私の梱包タイプを瓶のままにしたものです –

関連する問題