Michael
Michael

Reputation: 153

Java sardine webdav client on Android

I am currently implementing a WebDAV client for Android, which is based on sardine (https://github.com/lookfirst/sardine). The Android-Client is targeted for API level 15 (min-Api level).

Right now I want to initialize the connection by using the Sardine Factory class like this:

sardine = SardineFactory.begin(user, password);

This piece of code is embedded within an Activity, that shall check if the credentials are valid. By pressing on the OK button of the Activity a AsyncTask is started which embeds the codeline above

AsyncTask<ServerCredentials, Void, ServerCredentials> verifyCredentialsTask = new AsyncTask<String[], Void, boolean>(){
            @Override
            protected boolean doInBackground(String[]...c) {
                try {
                   String user = c[0];
                   String password = c[1]
                   sardine = SardineFactory.begin(user, password);
                   return true;
                }
                catch (Exception e) {
                   return false;
                }

            };

            @Override
            protected void onPostExecute(ServerCredentials sc) {
                final Intent intent = new Intent();
                ...

                setAccountAuthenticatorResult(intent.getExtras());
                setResult(RESULT_OK);
                finish();
            }
        };

When I debug the android application, I get up to the point where sardine is initialzed first from the SardineFactory. If I step over this line, an ExceptionInInitializerError is thrown. Although, there is a try catch statement, the whole activity crashes and the following exception trace can be seen in the logcat window:

E/AndroidRuntime(10996): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(10996): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(10996):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(10996):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime(10996):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime(10996):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime(10996):    at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(10996): Caused by: java.lang.ExceptionInInitializerError
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:45)
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:34)
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:22)

I have already searched the web for an answer. The definition of the ExceptionInInitializerError is to generic (https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/ExceptionInInitializerError.html).

If I attach the source to my referenced sardine.jar I can debug into the begin methods, and their overloads. The final "begin" method, which is called is defined by

public static Sardine begin(String username, String password, ProxySelector proxy)
{
    try {
        return new SardineImpl(username, password, proxy);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

seems to cause the problem.

As you can see I already modified it with a try catch, to see if I can catch the exception that is thrown. But as soon as I step over the SardineImpl construtor, the ExceptionInInitializerError is thrown. I have no chance to catch it.

I assume, that some library is still missing. I'm building the sardine.jar within eclipse by a maven build script (clean install). The source is unchanged except I added the following missing libraries

ant-1.9.2.jar
commons-codec-1.6.jar
commons-logging-1.1.3.jar
httpclient-4.5.jar
httpcore-4.3.2.jar
slf4j-api-1.7.12.jar
slf4j-jdk14-1.7.12.jar

The hooks in the Eclipse project settings (Java Build Path -> Order and Export) are set for all external libraries. Therefore I assume nothing is missing, when the APK is build and installed on the target device.

Does anyone has experienced a similar problem? How can I interpret the ExceptionInInitializerError exception?

Upvotes: 0

Views: 3153

Answers (3)

Michael
Michael

Reputation: 153

just to close this issue. Due to the fact, that I wanted to access an ownCloud instance via webdav i decided to drop the sardine library and go for the native ownCloud library (https://github.com/owncloud/android-library). This library included a pretty good sample client and worked perfect for my project.

Thanks

Upvotes: 1

Jaka
Jaka

Reputation: 1423

i have similar problems trying to make Sardine work on Android. I am using Android Studio, building with SDK 21. I simply downloaded the Sardine-Android sources and added them to the project in the folder /app/src/main/java and simple-xml-2.6.3.jar in the /app/libs. I am using ActionBarActivity. The code builds without errors. I however get another error in the same line, but not NoClassDefFoundError

Upvotes: 0

Michael
Michael

Reputation: 153

I was able to overcome the issue by using the Sardine Library, which was rewritten for Android as an Android-Library project (https://github.com/aflx/Sardine-Android). I imported the project into my Eclipse Workspace, built it and linked the jar file from the bin subdirectory into my project. Finally I had to set the hook in the project's settings "Build Path" -> "Order and Export".

This solution solved the issue above. Now, I am one step further, but still get an exception. When I try to list the files and folder on the remote server with the following code line

List<DavResource> res = sardine.list(hostName);

I get an NoClassDefFoundError which tells me that he couldn't find the class org.simpleframework.xml.core.Persister.

E/AndroidRuntime(26434): Caused by: java.lang.NoClassDefFoundError: org.simpleframework.xml.core.Persister

Within the project settings of the Sardine-Android I have linked the

simple-xml-2.6.2.jar

which should contain the missing class. Furthermore I have read in other sites (http://android.phonesdevelopers.com/1011_19444554/), that it might be necessary to exclude classes from the build path, because they might conflict with build in classes. Unfortunately, they are working with gradle, which I haven't worked with yet. I will search the web for a solution, but maybe someone knows hot to do this?

Upvotes: 0

Related Questions