android-library icon indicating copy to clipboard operation
android-library copied to clipboard

NullPointerException and HOST_NOT_AVAILABLE result after ReadRemoteOperation

Open mikedolx opened this issue 5 years ago • 15 comments

Hi,

I'm currently updating my app to use Android Studio and gradle, therefore i use the opportunity to upgrade the ownCloud library to the latest available version (including the new okhttp reference).

After upgrading my app to Gradle and AS i tested it within an emulator and found an issue when performing the ReadRemoteFolderOperation() on any of my test instances (which are ownCloud and Nextcloud server).

The immediate result after stepping over the ReadRemoteFolderOperation is "HOST_NOT_AVAILABLE". When i open the browser on the emulator and browse to the front page of my ownCloud instance it's working - i can also login.

When i take a look into the logcat i can observe the following two Exceptions:

E/ReadRemoteFolderOperation: Synchronized /: Unexpected exception
java.lang.IllegalArgumentException: account is null
    at android.accounts.AccountManager.getUserData(AccountManager.java:507)
    at com.owncloud.android.lib.common.accounts.AccountUtils.getUserId(AccountUtils.java:198)
    at com.owncloud.android.lib.common.OwnCloudClient.getUserFilesWebDavUri(OwnCloudClient.java:262)
    at com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation.run(ReadRemoteFolderOperation.java:79)
    at com.owncloud.android.lib.common.operations.RemoteOperation.runOperation(RemoteOperation.java:252)
    at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:215)

com.owncloud.android.lib.common.http.HttpClient: Could not setup SSL system.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getFilesDir()' on a null object reference
    at com.owncloud.android.lib.common.network.NetworkUtils.getKnownServersStore(NetworkUtils.java:89)
    at com.owncloud.android.lib.common.http.HttpClient.getOkHttpClient(HttpClient.java:78)
    at com.owncloud.android.lib.common.http.methods.HttpBaseMethod.<init>(HttpBaseMethod.java:58)
    at com.owncloud.android.lib.common.http.methods.webdav.DavMethod.<init>(DavMethod.java:51)
    at com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod.<init>(PropfindMethod.java:52)
    at com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation.run(ReadRemoteFolderOperation.java:81)
    at com.owncloud.android.lib.common.operations.RemoteOperation.runOperation(RemoteOperation.java:252)
    at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:215)

I can't get a clue out of this exception.

Here is how i run the 1st variant:

ReadRemoteFolderOperation readRemoteFolder = new ReadRemoteFolderOperation(folderInCloud);
	RemoteOperationResult readRemoteFolderResult = readRemoteFolder.execute(ocClient);
	ResultCode resultCode = readRemoteFolderResult.getCode();

Here is how i run the 2nd variant:

ReadRemoteFolderOperation readOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR);
RemoteOperationResult result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
result = readOperation.execute(ownCloudClient);

Here is how is setup my ownCloudClient instance:

ocClient = new OwnCloudClient(serverCredentials.getHostUri());
ocClient.setFollowRedirects(true);
// the out commente lines below were shown in the sample_client, 
// but it doesn't seem to work either
//		ocClient.setCredentials(
//				OwnCloudCredentialsFactory.newBasicCredentials(
//						serverCredentials.getUsername(),
//						serverCredentials.getPassword()
//				));
ocClient.setBaseUri(serverCredentials.getHostUri());
OwnCloudAccount ocAccount = new OwnCloudAccount(serverCredentials.getHostUri(), serverCredentials);
ocClient.setAccount(ocAccount);

serverCredentials is a class derived from OwncloudCredentials. The only method i override is the applyTo method. Here is how it looks:

@Override
public void applyTo(OwnCloudClient ownCloudClient) {
	// this is old code from the pre AS gradle era. 
	// The methods getParams() and getState weren't available on the new library anymore
	//		List<String> authPrefs = new ArrayList<String>(1);
	//        authPrefs.add(AuthPolicy.BASIC);
	//        ownCloudClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);        
	//        
	//        ownCloudClient.getParams().setAuthenticationPreemptive(true);
	//        ownCloudClient.getState().setCredentials(AuthScope.ANY,
	//        		new UsernamePasswordCredentials(userName, password)
	//		);
	
	// Clear previous basic credentials
    HttpClient.deleteHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER);
    HttpClient.deleteHeaderForAllRequests(HttpConstants.COOKIE_HEADER);

    HttpClient.addHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER,
            Credentials.basic(userName, password));

    Uri baseUri = this.getHostUri();

	OwnCloudAccount ocAccount = new OwnCloudAccount(baseUri, this);
    ownCloudClient.setAccount(ocAccount);
    ownCloudClient.setBaseUri(baseUri);
}

From the stack trace of the first exception, i would assume, that i need a working ownCloud-account on my mobile/emulator (which doesn't make sense to me). I set up the official ownCloud app, which was working fine.

Does anyone have an idea what could be the problem?

Thanks in advance,

Michael

mikedolx avatar Nov 21 '18 22:11 mikedolx

Hi @mikedolx , I would recommend you to analyze the network requests so you can know exactly what's happening under the hood.

You can try https://developer.android.com/studio/profile/network-profiler for that purpose, have a look at the response after performing the ReadRemoteOperation and even compare with the same operation executed by the official ownCloud app. There could be some headers you are not properly sending, server url is not properly built and so on.

You can copy-paste here your conclusions and we will think in another solution if this is not enough.

davigonz avatar Nov 22 '18 13:11 davigonz

Hi @davigonz, thanks for the replay. I'm sorry i haven't noticed it (maybe need to check my mail settings). I'll try your suggestion and report back,

mikedolx avatar Nov 26 '18 21:11 mikedolx

Hi, so i checked the Network profiler while running my App and debugging/stepping over the ReadRemoteOperation line. The network profiler doesn't show anything when debugging my app. It seems that the app doesn't send anything out. I'll try the ownCloud app by tomorrow. I guess i will have to compile the app from source? Otherwise i don't know how to attach to a different process on the emulator.

mikedolx avatar Nov 26 '18 21:11 mikedolx

Hi, now i was able to debug a little bit and create some results. I did the following:

  1. execute small code snippet with OkHttpClient to check if internet connection is ok within my App/Emulator
  • the code finished successfully.
  • Within the network profiler i could see a peak (see screen shot)

Here is the code snipped i used:

OkHttpClient okHttpClient = new OkHttpClient();

Request request = new Request.Builder()
        .url("http://example.com")
        .build();
try {
    Response response = okHttpClient.newCall(request).execute();
}
catch (IOException iex) {

}

grafik

  1. run and debug the owncloud Library sample client with my server/credentials. I had the same result as with my app, meaning nothing to see in the network profiler (see attached screen shot).

grafik

Within the sample_client i changed the startRefresh method as follows:

private void startRefresh() {
	ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR);
	RemoteOperationResult result = refreshOperation.execute(mClient);
}

If i use the method variant with the mHandler and i set a break to the onRemoteOperationSuccess method the resuslt is the same (HOST_NOT_AVAILABLE)

I repeated the procedure with a real mobile device with the same result.

It seems to me that i am doing something wrong?

mikedolx avatar Nov 28 '18 07:11 mikedolx

Did i mention, that my instance is an Nextcloud instance?

I tested the official owncloud app with my instance, but also with an public hoster (https://ppp.woelkli.com) and wasn't able to log in. I tried it with the emulator and a real smartphone.

The app always says "precondiction failed".

Are there any known incompatibilities with nextcloud?

mikedolx avatar Nov 29 '18 07:11 mikedolx

Are there any known incompatibilities with nextcloud?

The ownCloud app for Android is prepared and tested to work with ownCloud instances, we can not ensure the same for NextCloud ones.

Take into account that the ownCloud and Nextcloud code have diverged and will be probably different.

davigonz avatar Nov 30 '18 11:11 davigonz

Changing implementation of 'com.github.owncloud:android-library:oc-android-library-0.9.24' to 'com.github.owncloud:android-library:oc-android-library-0.9.21' solved similar issue for me:

dependencies { ... implementation 'com.github.owncloud:android-library:oc-android-library-0.9.21' }

ateachment avatar Dec 20 '18 16:12 ateachment

Hi @mikedolx Are you solved this error? because i'm stuck in this code. Error : account is null

authenticode avatar Apr 28 '21 10:04 authenticode

Hi @authenticode ,

I'm still stuck. Actually i haven't tried it since my last comment in 2018. I would have to dig it out again. I do plan to upgrade my app in a few weels, but currently i have other open projects.

mikedolx avatar May 02 '21 21:05 mikedolx

Hey @authenticode, how do you create the OwnCloudClient? Do you set the OwncloudAccount?

Could you tell me exactly where the NPE is thrown?

abelgardep avatar May 03 '21 07:05 abelgardep

Hey @abelgardep , yeah i'm already set OwnCloudClient and also OwnCloudAccount. But when i'm tried to get RemoteFiles then app crashed and through error of Account null

authenticode avatar May 03 '21 11:05 authenticode

Hey @mikedolx, Okay thanks, I'm also stuck in this. because i'm getting any docs about basic authentication

authenticode avatar May 03 '21 11:05 authenticode

@abelgardep You can check screenshot image

authenticode avatar May 03 '21 14:05 authenticode

Thanks, @authenticode, I can see that you use this OwnCloudAccount constructor to build the ownCloudAccount. We use AccountManager in the android App to handle multi-account properly. And as you can see here it will try to retrieve the baseUrl from the saved account in AccountManager. If you don't use the AccountManager, it will fail because this baseUrl won't be found.

Please try to build the OwnCloudAccount with this constructor and let me know if you are able to perform operations. 👍

abelgardep avatar May 04 '21 06:05 abelgardep

@abelgardep , Yeah i'm also tried this but not working. baseUrl worked when on OCServerInfoService().getRemoteStatus you can check screenshot. You can check my github code. https://github.com/PrinceAuth/OwnCloudDemoPrince.git image image

authenticode avatar May 04 '21 08:05 authenticode