I have an Android test project using Espresso that I am attempting to build with Ant. I can build the test application just fine. Install it to the device and everything. The problem is, whenever I try to run the test with
adb shell am instrument -w
com.test.package/com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner
I get this in my command prompt:
INSTRUMENTATION_RESULT: shortMsg=java.lang.ClassNotFoundException
INSTRUMENTATION_RESULT: longMsg=java.lang.ClassNotFoundException: Didn't find class "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner" on path: /system/framework/com.google.android.maps.jar:/system/framework/android.test.runner.jar:/data/app/test.apk:/data/app/myApp.apk
INSTRUMENTATION_CODE: 0
And this in the logcat:
E/AndroidRuntime(27558): java.lang.RuntimeException: Unable to
instantiate instrumentation
ComponentInfo{com.avai.app.test.automate/com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner}:
java.lang.ClassNotFoundException: Didn't find class
"com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
on path:
/system/framework/com.google.android.maps.jar:/system/framework/android.test.runner.jar:/data/app/test.apk:/data/app/myApp.apk
I can run the tests in Eclipse if I check the box next to my Espresso jar under Configure Build Path->Order and Export. I noticed that with this box unchecked I get the exact same error message as above.
What I need to know is how to emulate Eclipse's behavior here with Ant?
Here is a snippet from my build.xml file (mostly generated from Export->Ant build files in Eclipse:
<path id="Android 4.4.2.libraryclasspath">
... (lots of jars) ...
</path>
<path id="AutomationTests.classpath">
... (more jars) ...
</path>
<path id="AutomationTests.classpath">
<pathelement location="bin/classes"/>
<path refid="Android 4.4.2.libraryclasspath"/>
<path refid="Android Private Libraries.libraryclasspath"/>
<path refid="Android Dependencies.libraryclasspath"/>
<pathelement location="../../android-test-kit/bin/espresso-standalone/espresso-1.1-bundled.jar"/>
</path>
<javac encoding="${java.encoding}" source="${java.source}"
target="${java.target}"
debug="true" extdirs="" includeantruntime="false"
destdir="${out.classes.absolute.dir}"
bootclasspathref="project.target.class.path"
classpathref="project.javac.classpath">
...(stuff) ...
</javac>
The error you're seeing is caused by the third-party jar not being packaged inside the APK.
The default behaviour of the android ant build is that only the jars found in application project /libs folder are packaged into the apk.
Copy the espresso-1.1-bundled.jar to the /libs folder of the app project and you'll be fine.
Another thing to consider - you'll be better off generating the build.xml with Android tools as described here: http://developer.android.com/tools/projects/projects-cmdline.html#UpdatingAProject
Related
We are trying to get the libphonenumber to run in our java project.
The java project is running as a service on one of our servers.
On our local machines, we are using the following shell commands to include the libraries (please ignore the version numbers):
export ANT_HOME="C:\DEV\apache-ant-1.9.16"
export JAVA_HOME="C:\Program Files\Java\jdk-15.0.2"
export MAVEN_HOME="C:\DEV\apache-maven-3.8.6"
export PATH=${PATH}:${JAVA_HOME}/bin:${ANT_HOME}/bin:${MAVEN_HOME}/bin
export MB_API_HOME="C:\DEV\java-rest-api\api\target"
After we run the "ant" command, we move the result file (jar) on our server in the respective folder.
These are the 3 files that are needed for the library:
We have copied them on the server, in the respective lib folder.
Everything runs fine until the following error shows up:
java.lang.NoClassDefFoundError: com/google/i18n/phonenumbers/PhoneNumberUtil
This happens when it comes to the following line:
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
We have found the following code on this website (https://www.baeldung.com/java-libphonenumber), where it is explained that this has to go to a pom-xml file:
<dependency>
<groupId>com.googlecode.libphonenumber</groupId>
<artifactId>libphonenumber</artifactId>
<version>8.12.10</version>
</dependency>
We have no clue which pom.xml they are writing about. These are the files that are being found by IntelliJ:
IntelliJ has no problems finding the classes and their methods when we type in the code window.
What else do we have to do and consider to get it to run on the server?
Thanks in advance.
Edit 1 of ?: As g00se suggested, we already have the class path mentioned in the build.xml, which looks like this:
I had the idea of removing the libphonenumber.jar from the lib folder on the server itself to see if we receive a different error. But it is still the same NoClassDefFoundError. It is as if the result file of ant has no clue about libphonenumber at all!
Edit 2 of ?:
I have experimented with this library on my private computer.
If I click on the run icon (1), it seems to work, as seen in (2).
However, going to the folder with the Main class (3) and running java Main, leads to the same error:
But then, I just copied the classes into the folder where the Main is, and the error changed:
Here is the snippet in the build.xml of my private project:
<target name="compile" depends="init"
description="compile the source">
<!-- Compile the Java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}">
<classpath>
<pathelement path="jars/libphonenumber.jar"/>
</classpath>
</javac>
</target>
I guess I am missing the right approach here, do I?
Edit 3 of ?: I created a repository of my private/test project.
Here it is: https://github.com/3rc4n/libphonenumberexperiment
I have some legacy Java 6 project and I want to bring some updates on them like Java 8 time library. I found that is possible by using ThreeTen backport. But I don't know how to use it with Ant build tool. Any good references or examples please ?
Overview:
Download the ThreeTen Backport JAR file into the lib folder of your Ant project
Make sure that JAR files in your lib folder are on the classpath for both compilation and running (this may already be the case).
In your Java source files add imports from org.threeten.bp with subpackages and use the imported classes in your code.
Download JAR
On http://www.threeten.org/threetenbp/, at the top select Releases -> Download to get to the Maven repository. In the first search result (currently threetenbp 1.3.6 from 10-Jul-2017), in the Download column click jar. Download the file (in this case threetenbp-1.3.6.jar) to or move it to the lib folder of your Ant project. Or where you’ve got your external JARs. If you haven’t got such a place, create a folder called lib for it.
Fix your classpath
If you haven’t previously got any external dependencies in the form of external JAR files that your program uses, you may need to prepare your build.xml file for these. In my build.xml I added
<property name="lib.dir" value="lib"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
This defines names for the lib folder and the classpath for use later. Note that I specify that all .jar files in the lib folder with subfolders are on the classpath, so in the future you can just drop JARs in to add them to your project. Then I added the classpath both to my compile target and to my run target:
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
</target>
And
<target name="run" depends="jar">
<java fork="true" classname="${main-class}">
<classpath>
<path refid="classpath"/>
<path location="${jar.dir}/${ant.project.name}.jar"/>
</classpath>
</java>
</target>
We need to fix both targets because the external JAR(s) is/are needed both for compilation and for running.
Use java.time classes in your Java program
Here’s my program. Note that the import statements refer to org.threeten.bp.
package ovv.ant.threetenbp;
import java.util.Date;
import org.threeten.bp.Instant;
import org.threeten.bp.DateTimeUtils;
public class AntAndThreeTenBackportDemo {
public static void main(String... commandLineArguments) {
Instant once = Instant.parse("1939-11-19T16:30:00Z");
Date oldfashionedDateObject = DateTimeUtils.toDate(once);
System.out.println("As Date: " + oldfashionedDateObject);
}
}
When I run from Ant (on my computer in Europe/Copenhagen time zone) I get:
run:
[java] As Date: Sun Nov 19 17:30:00 CET 1939
I used Ant 1.9.7, but I think it’s the same in other versions.
Source and further reading
I used the Ant tutorial here, in particular the Using External Libraries section.
I am using a short ant script to generate my Clover coverage report. I want to exclude certain source files from the report. The code is already fully instrumented, it's not feasible for me to exclude the file during instrumentation.
Excerpt of the ant build xml (trimmed):
<project name="Clover Coverage" default="clover.report" basedir="${basedir}">
<target name="clover.report">
<clover-report initstring="${cloverdb}" >
<current outfile="${reportdir}" title="${title}" >
<format type="html"/>
<sourcepath>
<pathelement path="${srcdir1}"/>
</sourcepath>
</current>
</clover-report>
</target>
</project>
I've tried to exclude this using fileset, but when I do this, Clover gives an error message saying that no coverage info could be found. But if I remove the fileset then it works fine.
My attempted fix that doesn't work:
<current outfile="${reportdir}" title="${title}" >
<format type="html"/>
<fileset dir="${srcdir1}">
<exclude name="**/ExcludeThisClass.java"/>
</fileset>
<sourcepath>
<pathelement path="${srcdir1}"/>
</sourcepath>
</current>
Is the exclusion of files from the Clover report not possible?
Please run your Ant with debug logging (ant -d). The <clover-report> task should print more details then. The most probably you instrumented and/or executed your source code not at once but in several build/test sessions.
And it's probable that Clover rejected some of recording files because it found them out of date.
See these knowledge base articles:
https://confluence.atlassian.com/cloverkb/ignoring-coverage-recording-files-300816998.html
https://confluence.atlassian.com/cloverkb/no-coverage-recordings-found-no-report-will-be-generated-611812757.html
I have a java project which imports and uses classes in other projects. I am able to successfully build this project in eclipse. From eclipse I then exported an Ant Buildfile, build.xml. If I attempt to run this file with eclipse or via cmd prompt it fails.
One of the many import reported error is:
[javac] H:...\sortedprovidablemanagertest\SimpleObject.java:8: error: package com.rock.common.core.providable.abstractions does not exist
[javac] import com.rock.common.core.providable.abstractions.AProvidable;
How do I tell Ant to import required classes. I'm guessing these are dependencies. But clearly I'm having trouble setting it up correctly.
In the build.xml, there will be a <javac> task. <javac> takes either a classpath attribute or a nested <classpath> element. Here's an example with a nested <classpath> element:
<javac ...>
<classpath>
<pathelement location="PATH_TO_THE_CLASS_FILES_ROOT_DIRECTORY"/>
</classpath>
...
</javac>
The classpath tells the Java compiler where to find the binary dependencies it needs.
For the life of me, I am trying to get FindBugs (2.0.1) to run as part of my command-line Ant build. I downloaded the FindBugs JAR and extracted it to /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1:
As you can see in the screenshot, under /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib there is a JAR called bcel-1.0.jar, and if you open it, you can see that I have drilled down to a class called org.apache.bcel.classfile.ClassFormatException. Hold that thought.
I then copied /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib/findbugs-ant.jar to ${env.ANT_HOME}/lib to make it accessible to the version of Ant that is ran from the command-line (instead of the Ant instance that comes built-into Eclipse).
My project directory structure is as follows:
/home/myuser/sandbox/workbench/eclipse/workspace/myapp/
src/
main/
java/
test/
java/
build/
build.xml
build.properties
gen/
bin/
main/ --> where all main Java class files compiled to
test/ --> where all test Java class files compiled to
audits/
qual/
staging/
Inside build.xml:
<project name="myapp-build" basedir=".." default="package"
xmlns:fb="antlib:edu.umd.cs.findbugs">
<path id="findbugs.source.path">
<fileset dir="src/main/java">
<include name="**.*java"/>
</fileset>
<fileset dir="src/main/test">
<include name="**.*java"/>
</fileset>
</path>
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
uri="antlib:edu.umd.cs.findbugs"/>
<!-- Other Ant target omitted for brevity. -->
<target name="run-findbugs">
<!-- Create a temp JAR that FindBugs can use for analysis. -->
<property name="fb.tmp.jar" value="gen/staging/${ant.project.name}-findbugs-temp.jar"/>
<echo message="Creating ${fb.tmp.jar} for FindBugs."/>
<jar destfile="gen/staging/${ant.project.name}-findbugs-temp.jar">
<fileset dir="gen/bin/main" includes="**/*.class"/>
<fileset dir="gen/bin/test" includes="**/*.class"/>
</jar>
<echo message="Conducting code quality tests with FindBugs."/>
<fb:findbugs home="/home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1"
output="html" outputFile="gen/audits/qual/findbugs.html" stylesheet="fancy-hist.xsl" failOnError="true">
<sourcePath refid="findbugs.source.path"/>
<class location="${fb.tmp.jar}"/>
</fb:findbugs>
</target>
<target name="echoMsg" depends="run-findbugs">
<echo message="The build is still alive!!!"/>
</target>
</project>
But when I run ant -buildfile build.xml echoMsg from the command-line, I get an error in FindBugs:
run-findbugs:
[echo] Creating gen/staging/myapp-build-findbugs-temp.jar for FindBugs.
[jar] Building jar: /home/myuser/sandbox/workbench/eclipse/workspace/myapp/gen/staging/myapp-build-findbugs-temp.jar
[echo] Conducting code quality tests with FindBugs.
[fb:findbugs] Executing findbugs from ant task
[fb:findbugs] Running FindBugs...
[fb:findbugs] Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/bcel/classfile/ClassFormatException
[fb:findbugs] Caused by: java.lang.ClassNotFoundException: org.apache.bcel.classfile.ClassFormatException
[fb:findbugs] at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
[fb:findbugs] at java.security.AccessController.doPrivileged(Native Method)
[fb:findbugs] at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[fb:findbugs] at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[fb:findbugs] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[fb:findbugs] at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[fb:findbugs] Could not find the main class: edu.umd.cs.findbugs.FindBugs2. Program will exit.
[fb:findbugs] Java Result: 1
[fb:findbugs] Output saved to gen/audits/qual/findbugs.html
echoMsg:
[echo] The build is still alive!!!
Here's what has me amazed:
Even with failOnError="true", FindBugs is not halting the build even when this runtime exception is encountered
The last piece of output "Output saved to gen/audits/qual/findbugs.html" is a lie! There is nothing in gen/audits/qual!
The bcel-1.0.jar is absolutely under FindBugs home, just like every other JAR in the lib/ directory.
Please note: the findbugs-ant.jar is definitely copied to ANT_HOME/lib; otherwise I would be getting a failed build complaining that it couldn't find the Ant tasks. As a sanity check, I went ahead and did this (I deleted the findbugs-ant.jar from ANT_HOME/lib and got a failed build). This build doesn't fail (it succeeds!). It just doesn't run findbugs.
Can anyone spot what is going on here? Thanks in advance!
You can debug where BCEL is being loaded from using the -verbose:class argument to the jvm.
To pass this argument to the jvm running findbugs, use the jvmargs flag on the find bugs plugin
jvmargs
Optional attribute. It specifies any arguments that should be
passed to the Java virtual machine used to run FindBugs. You may need
to use this attribute to specify flags to increase the amount of
memory the JVM may use if you are analyzing a very large program.
How did you populate the find bugs lib jar? When I download findbugs.zip, I get a lib directory which looks very different than what you show. In particular, mine contains a bcel with a version of 5.3, not 1.0 as you show.
Funny thing because I am using the same version of Findbugs and the jar file is named bcel.jar not bcel-1.0.jar. I am also running Findbugs from an Ant script. As crazy as it might sound, try to download the Findbugs once again, unpack it in the place of your current one and run your script once again.
My guess is that you actually have BCEL in the classpath twice. And the file is being loaded from the jar outside the FindBugs library. Then, when FindBugs tries to load the jar, it finds the BCEL in the FindBugs library and cannot load it, because it's already loaded.
The solution would be to find where else BCEL exists in the classpath and remove it.
You might have to define a AuxClasspath to include the classpath that your <javac> task used when compiling your class files.
You don't show how the compile took place, so I am assuming your created a compile.classapath classpath reference:
<javac destdir="gen/bin/main"
srcdir="src/main/java"
classpathref="compile.classpath"/>
<fb:findbugs home="/home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1"
output="html" outputFile="gen/audits/qual/findbugs.html" stylesheet="fancy-hist.xsl" failOnError="true">
<auxClasspath refid="compile.classpath"/>
<sourcePath refid="findbugs.source.path"/>
<class location="${fb.tmp.jar}"/>
</fb:findbugs>
I don't see from your Ant script that bcel is landing on any classpath that the findbugs task would be able to load it from. You might want to try making your taskdef explicitly include everything findbugs needs.
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
uri="antlib:edu.umd.cs.findbugs">
<classpath>
<fileset dir="/home/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1">
<include name="*.jar"/>
</fileset>
</classpath>
</taskdef>
most classpath problems you can debug with tattle. it will report you all jars in your project. all duplicated classes etc. saved me a lot of time.
there is also ant task ready: http://docs.jboss.org/tattletale/userguide/1.2/en-US/html/ant.html