UserServiceException thrown attempting to save user after updating a 1:N relationship property

When attempting to save a BackendlessUser after updating a 1:N relationship field, I am consistently throwing this exception.

The relationship field is called “contacts” and is a 1:N relationship to a custom POJO called “Contact”

public class Contact {
  private double compatibilityScore;
  private boolean blocked;
  private BackendlessUser user;
  public Contact() {
  }

  // getters and setters omitted for brevity
}

Contact.user is a 1:1 relationship with an existing user which a user, in this “me,” wants to add to their contact list, which is stored in the “contacts” user property.

When attempting to save, the exception is consistently thrown after doing the following on the line where I save the user.

Contact c = new Contact();
c.setBlocked( false );
c.setCompatibilityScore( 0.0 );
c.setUser( someUser );

List<Contact> myContactList = new ArrayList<>();
myContactList.add( c );

me.setProperty( "contacts", myContactList );
BackendlessUser savedMe = Backendless.Persistence.of( BackendlessUser.class ).save( me );

I have a stack trace for it, which states the exception is thrown in FootprintsManager, specifically in updateFootprintForObject:

{
“___jsonclass”: “java.lang.StackTraceElement”,
“fileName”: “FootprintsManager.java”,
“nativeMethod”: false,
“methodName”: “updateFootprintForObject”,
“className”: “com.backendless.FootprintsManager$Inner”,
“lineNumber”: 369
},

The throwable for the BackendlessException that’s caught indicates that a NoSuchField Exception is being thrown:
“___jsonclass”: “java.lang.NoSuchFieldException”,
“localizedMessage”: null,
“cause”: {
“___objectref”: 17
},
“stackTrace”: [
{
“___jsonclass”: “java.lang.StackTraceElement”,
“fileName”: “Class.java”,
“nativeMethod”: false,
“methodName”: “getDeclaredField”,
“className”: “java.lang.Class”,
“lineNumber”: 2070
},

Any help is much appreciated,
-Ian

Hi Ian!

Could you provide your application Id?
Regards,
Kate.

Do you have “autoload” enabled for some of these related properties?

Hi Kate,
Thanks for getting back to me. My application id is E2FCAB80-B95E-E671-FFF9-A587FA266900. Autoload is not enabled for the resources I am attempting to load and save. I should add that I have attempted to use autoload to rule that out as a cause, and I threw the same exception; consequently, since it didn’t help, I have since disabled autoload.
-Ian

Hi,
Just checking in to see if there were any updates from Backendless about this issue?

Thanks,
-Ian

Hi Ian!

We can not reproduce this issue on our side.
I sent you my data structure and sample code.
Please check if all is correct.
Regards,
Kate.

Hi Ian,

Have you tried updating backendless.jar? Seems this problem has already been fixed in the latest version.
Here is a link where you can download it: https://backendless.com/mobile-developers/

Regards,
Sergey

HI Sergey and Kim,
I am still able to reproduce this issue. I’m not sure if I mentioned this before, but this code is running as an API endpoint using Backendless custom business logic/hosted service functionality.

I am developing against the Backendless 3.0 jar in a Maven project, however, my pom.xml is currently using whatever provided SDK is available to custom business logic on the server-side, as I am not able to successfully upload the project when the Backendless 3.0 jar is included as a dependency with any scope besides “provided.”

-Ian

Could you please share your pom.xml?

Sergey,
Here’s my pom.xml. Currently, in development, I am using the Backendless 3.0 SDK dependency from my local maven repository. I could not find this library version available at Maven Central.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>some project name</name>
<groupId>com.someorganization</groupId>
someartifactId
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!–<dependency>–>
<!–<groupId>com.backendless</groupId>–>
<!–<artifactId>android–>
<!–<version>2.0.1</version>–>
<!–<scope>provided</scope>–>
<!–</dependency>–>
<dependency>
<groupId>com.backendless</groupId>
android
<version>3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
httpclient
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
json
<version>20150729</version>
</dependency>
<dependency>
<groupId>com.nexmo</groupId>
nexmoSdk
<version>1.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
maven-assembly-plugin
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>

<manifest>
true
<packageName>com.somecompany.somepackage</packageName>
<mainClass>com.somecompany.hostedbusinesslogic</mainClass>
</manifest>

</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
maven-jar-plugin
<version>2.6</version>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>

Hi guys,
Just checking in to see if there was any feedback about this? I am still unable to save a user without throwing an exception somewhere in FootPrintsManager. I am able to replicate this consistently.

Is Backendless 3.0 available to my Hosted API Service/Custom Business Logic jar? The indication I get is that it may not be, as the line numbers I’m seeing in the stack trace from the exception’s cause don’t match up with what I’m seeing in the Backendless 3.0 jar in my local project.

Thanks,

-Ian

We shall update Android SDK on Maven soon. Until that, you may try to use the jar directly, not through Maven.

Sergey,
Is it possible that the Hosted Service API code which I’m uploading to Backendless is running against an older library version of the Backendless SDK?

See the below stack trace, thrown on the server-side when testing the API endpoints I have written:

{
"___jsonclass": "java.lang.StackTraceElement",
"fileName": "FootprintsManager.java",
"nativeMethod": false,
"methodName": "updateFootprintForObject",
"className": "com.backendless.FootprintsManager$Inner",
"lineNumber": 369
},

In my local version of the Backendless 3.0 jar, which i re-downloaded and re-installed from the link you provided me earlier in this thread, there is no line 369 in FootPrintsManager.

Is it possible to verify that the jar files I upload to Backendless are actually running against Backendless SDK 3.0? I am unable to upload a jar with the Backendless SDK included as a dependency, so I’m not sure of any other action I can take if this is the case and the library version provided by Backendless is older than 3.0

Thank you,
-Ian

You should have backendless.jar in libs folder, which you downloaded from Business Logic tab. Try to update it there and then deploy.

Sergey,

This code is not a timer or trigger, it is a Hosted Service API which implements IBackendlessService.

-Ian

Hi Ian,

We have updated the backendless.jar library on the production server. Could you please try your code again?

Regards,
Mark

Mark,
Still experiencing the same exception thrown at the same spot.

Here’s the stack trace:

{
  "trace": [
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "FootprintsManager.java",
      "nativeMethod": false,
      "methodName": "updateFootprintForObject",
      "className": "com.backendless.FootprintsManager$Inner",
      "lineNumber": 369
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "FootprintsManager.java",
      "nativeMethod": false,
      "methodName": "updateFootprintForObject",
      "className": "com.backendless.FootprintsManager$Inner",
      "lineNumber": 357
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "Persistence.java",
      "nativeMethod": false,
      "methodName": "save",
      "className": "com.backendless.Persistence",
      "lineNumber": 112
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "HeyStaxContactController.java",
      "nativeMethod": false,
      "methodName": "addContact",
      "className": "com.oovoolabs.heystax.restAPI.user.HeyStaxContactController",
      "lineNumber": 113
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "HeyStaxAPI.java",
      "nativeMethod": false,
      "methodName": "addNewContact",
      "className": "com.oovoolabs.heystax.restAPI.HeyStaxAPI",
      "lineNumber": 81
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "NativeMethodAccessorImpl.java",
      "nativeMethod": true,
      "methodName": "invoke0",
      "className": "sun.reflect.NativeMethodAccessorImpl",
      "lineNumber": -2
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "NativeMethodAccessorImpl.java",
      "nativeMethod": false,
      "methodName": "invoke",
      "className": "sun.reflect.NativeMethodAccessorImpl",
      "lineNumber": 62
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "DelegatingMethodAccessorImpl.java",
      "nativeMethod": false,
      "methodName": "invoke",
      "className": "sun.reflect.DelegatingMethodAccessorImpl",
      "lineNumber": 43
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "Method.java",
      "nativeMethod": false,
      "methodName": "invoke",
      "className": "java.lang.reflect.Method",
      "lineNumber": 497
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "Invocation.java",
      "nativeMethod": false,
      "methodName": "invoke",
      "className": "weborb.util.Invocation",
      "lineNumber": 190
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "Invocation.java",
      "nativeMethod": false,
      "methodName": "invoke",
      "className": "weborb.util.Invocation",
      "lineNumber": 62
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "ServiceInvocationTask.java",
      "nativeMethod": false,
      "methodName": "runImpl",
      "className": "com.backendless.coderunner.runtime.task.ServiceInvocationTask",
      "lineNumber": 93
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "ExtendedRunnable.java",
      "nativeMethod": false,
      "methodName": "run",
      "className": "com.backendless.coderunner.runtime.concurrent.ExtendedRunnable",
      "lineNumber": 22
    },
    {
      "___jsonclass": "java.lang.StackTraceElement",
      "fileName": "Thread.java",
      "nativeMethod": false,
      "methodName": "run",
      "className": "java.lang.Thread",
      "lineNumber": 745
    }
  ],
  "cause": {
    "___jsonclass": "java.lang.NoSuchFieldException",
    "localizedMessage": null,
    "cause": null,
    "stackTrace": [
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Class.java",
        "nativeMethod": false,
        "methodName": "getDeclaredField",
        "className": "java.lang.Class",
        "lineNumber": 2070
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ReflectionUtil.java",
        "nativeMethod": false,
        "methodName": "getField",
        "className": "com.backendless.utils.ReflectionUtil",
        "lineNumber": 65
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ReflectionUtil.java",
        "nativeMethod": false,
        "methodName": "getField",
        "className": "com.backendless.utils.ReflectionUtil",
        "lineNumber": 71
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ReflectionUtil.java",
        "nativeMethod": false,
        "methodName": "getField",
        "className": "com.backendless.utils.ReflectionUtil",
        "lineNumber": 71
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ReflectionUtil.java",
        "nativeMethod": false,
        "methodName": "getFieldValue",
        "className": "com.backendless.utils.ReflectionUtil",
        "lineNumber": 39
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "FootprintsManager.java",
        "nativeMethod": false,
        "methodName": "updateFootprintForObject",
        "className": "com.backendless.FootprintsManager$Inner",
        "lineNumber": 261
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "FootprintsManager.java",
        "nativeMethod": false,
        "methodName": "updateFootprintForObject",
        "className": "com.backendless.FootprintsManager$Inner",
        "lineNumber": 357
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Persistence.java",
        "nativeMethod": false,
        "methodName": "save",
        "className": "com.backendless.Persistence",
        "lineNumber": 112
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "HeyStaxContactController.java",
        "nativeMethod": false,
        "methodName": "addContact",
        "className": "com.oovoolabs.heystax.restAPI.user.HeyStaxContactController",
        "lineNumber": 113
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "HeyStaxAPI.java",
        "nativeMethod": false,
        "methodName": "addNewContact",
        "className": "com.oovoolabs.heystax.restAPI.HeyStaxAPI",
        "lineNumber": 81
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "NativeMethodAccessorImpl.java",
        "nativeMethod": true,
        "methodName": "invoke0",
        "className": "sun.reflect.NativeMethodAccessorImpl",
        "lineNumber": -2
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "NativeMethodAccessorImpl.java",
        "nativeMethod": false,
        "methodName": "invoke",
        "className": "sun.reflect.NativeMethodAccessorImpl",
        "lineNumber": 62
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "DelegatingMethodAccessorImpl.java",
        "nativeMethod": false,
        "methodName": "invoke",
        "className": "sun.reflect.DelegatingMethodAccessorImpl",
        "lineNumber": 43
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Method.java",
        "nativeMethod": false,
        "methodName": "invoke",
        "className": "java.lang.reflect.Method",
        "lineNumber": 497
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Invocation.java",
        "nativeMethod": false,
        "methodName": "invoke",
        "className": "weborb.util.Invocation",
        "lineNumber": 190
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Invocation.java",
        "nativeMethod": false,
        "methodName": "invoke",
        "className": "weborb.util.Invocation",
        "lineNumber": 62
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ServiceInvocationTask.java",
        "nativeMethod": false,
        "methodName": "runImpl",
        "className": "com.backendless.coderunner.runtime.task.ServiceInvocationTask",
        "lineNumber": 93
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "ExtendedRunnable.java",
        "nativeMethod": false,
        "methodName": "run",
        "className": "com.backendless.coderunner.runtime.concurrent.ExtendedRunnable",
        "lineNumber": 22
      },
      {
        "___jsonclass": "java.lang.StackTraceElement",
        "fileName": "Thread.java",
        "nativeMethod": false,
        "methodName": "run",
        "className": "java.lang.Thread",
        "lineNumber": 745
      }
    ],
    "suppressed": [],
    "message": null
  }
}

this happens when attempting to save a user after updating their “contacts” property, which is a 1:N relationship with the “HeyStaxContact” table. Here’s what I’m doing on the line which sets off the exception:

me.setProperty( "contacts", myContactList );


try
{
    BackendlessUser savedMe = Backendless.Persistence.save( me );
    response.put( "savedMe", savedMe );
}
catch( Exception ex )
{
    response.put( "cause", ex.getCause() );
    response.put( "trace", ex.getStackTrace() );
}

In this case, “me” is a BackendlessUser object that I’ve obtained through the following query:

List&lt;String&gt; related = new ArrayList&lt;&gt;();
related.add( "contacts.user" );


String whereClause = "objectId='" + objectId + "'";
QueryOptions queryOptions = new QueryOptions();
queryOptions.setRelated( related );
queryOptions.setRelationsDepth( 2 );


BackendlessDataQuery query = new BackendlessDataQuery( whereClause );
query.setQueryOptions( queryOptions );


BackendlessUser me = Backendless.Persistence.of( BackendlessUser.class ).find( query ).getData().get( 0 );

Happy to provide anything else you’d need to try and solve this. I’m hoping it’s something that I’m simply overlooking because I’ve been staring at the code too long…

Any help is greatly appreciated.Thanks,-Ian

Hey Ian,

I know both Kate and Alex worked on this issue and could not reproduce it. I am going to try it out myself now and will share my findings with you. One thing that is not clear to me is how do you invoke the code that eventually fails? I know it is a hosted service. Are there any special circumstances around the invocation? For example, security context, any pre-requisite state of the app, etc?

Regards,
Mark

Mark,

No special state of the app is required. The endpoint takes two arguments:

String myObjectId
and
String theirObjectId

which is used to query for each user, get and update their contact list, and then attempts to persist the user with the updated contact list.

I can provide whatever code you’d need to see what I’m doing if you’d like. Like I said, I have been staring at this for a while and may be overlooking something obvious, but as far as I can see, I’m not doing anything crazy.

Thanks,
-Ian

Mark,

I just had a breakthrough with this. Instead of setting the “contacts” property as a List<HeyStaxContact>, I persisted it as a HeyStaxContact[] like so:

HeyStaxContact[] testContactArray = myContactList.toArray( new HeyStaxContact[ myContactList.size() ] );
me.setProperty( "contacts", testContactArray );


BackendlessUser savedMe = Backendless.Persistence.of( BackendlessUser.class ).save( me );

is NOT throwing the exception. I have reproduced this consistently 3 times now.

I hope this helps,
-Ian