Skip to content

Conversation

dkimitsa
Copy link
Contributor

Background

issue #567.
not exact issue but same problem.
In general native-to-Java enum mapping is fragile in RoboVM as most likely app will crash if set of enum items in app differs from one available in system:

case 1: global value is not available on target os

(case as described in #567) -- fails with UnsatisfiedLinkError. Happens when app was built for newer API version but run on old device. As result global value is not available in the binary.

Root case: native to java marshaller code looks like bellow valueOf:

for (GlobalValueEnumeration v : values) {
  if (v.value().equals(value)) {
    return v;
}

If entry is missing -- v.value() will cause UnsatisfiedLinkError

the fix:

code to be added to check if v.isAvailable() before doing v.value().equals(value)

case 2: value is unknown for application.

Happens when marshalling value returned by system API and it is not known for application. Happens when old app runs on new OS. In this case same valueOf marshaller will not find the value in known values list and throw IllegalArgumentException("No constant with value").

the fix:

It is against enum concept (e.g. it has to be fixed runtime but GlobalValueEnumeration is not a true enum) - the fix is to dynamically create new entry of enumeration item and add it to values.

discussion

This PR updates only AVMetadataObjectType but in general all bindings for GlobalValueEnumeration to be updated

GlobalValueEnumeration is fragile and will cause a crash if set of enum items in app differs from one available in system:
## case 1: global value is not available on target os (case as described in MobiVM#567) -- fails with `UnsatisfiedLinkError`. Happens when build for newer API version but run on old device.
### Root case: native to java marshaller code looks like bellow `valueOf`:
```
for (GlobalValueEnumeration v : values) {
  if (v.value().equals(value)) {
    return v;
}
```
If entry is missing -- v.value() will cause `UnsatisfiedLinkError`

### the fix:
code to be added to check if `v.isAvailable()` before doying `v.value().equals(value)`

## case 2: value is unknown for application. API mightreturns value that was introduced in new version. In this case same `valueOf` marshaller will not find the value in known `values` list and throw  `IllegalArgumentException("No constant with value")`.
### the fix:
dynamicaly create new entry of enumeration item and add it to `values`. its nit perfect to extend enum runtime but its the only stable not having application crashing.
dkimitsa added a commit to dkimitsa/robovm-bro-gen that referenced this pull request Apr 7, 2021
@Tom-Ski Tom-Ski merged commit 752454f into MobiVM:master May 11, 2021
@dkimitsa dkimitsa deleted the fix/567 branch October 20, 2021 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants