Description
When using the Files API to call getFileStatus
, I'm getting a RESTEASY004655
error:
Exception in thread "main" com.smartling.api.v2.client.exception.RestApiRuntimeException: http_status=500, method=getFileStatus, fileUri=video-feature/src/main/res/values/strings.xml/HEAD
at com.smartling.api.v2.client.exception.RestApiExceptionHandler.createRestApiException(RestApiExceptionHandler.java:44)
at com.smartling.api.v2.client.exception.RestApiExceptionHandler.createRestApiException(RestApiExceptionHandler.java:23)
at com.smartling.api.v2.client.ExceptionDecoratorInvocationHandler.invoke(ExceptionDecoratorInvocationHandler.java:65)
at com.sun.proxy.$Proxy14.authenticate(Unknown Source)
at com.smartling.api.v2.client.auth.Authenticator.getAccessTokenInternal(Authenticator.java:121)
at com.smartling.api.v2.client.auth.Authenticator.refreshOrRequestNewAccessToken(Authenticator.java:100)
at com.smartling.api.v2.client.auth.Authenticator.getAccessToken(Authenticator.java:76)
at com.smartling.api.v2.client.auth.BearerAuthSecretFilter.getTokenString(BearerAuthSecretFilter.java:28)
at com.smartling.api.v2.client.auth.AbstractBearerAuthFilter.filter(AbstractBearerAuthFilter.java:19)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.filterRequest(ClientInvocation.java:687)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:489)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:152)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:115)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy21.getFileStatus(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.smartling.api.v2.client.ExceptionDecoratorInvocationHandler.invoke(ExceptionDecoratorInvocationHandler.java:50)
at com.sun.proxy.$Proxy22.getFileStatus(Unknown Source)
at com.foo.bar.MainKt$downloadStrings$fileStatuses$1$1$1.invokeSuspend(Main.kt:226)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Suppressed: com.smartling.api.v2.client.exception.RestApiRuntimeException: http_status=500, method=getFileStatus, fileUri=prelaunch-screen-feature/src/main/res/values/strings.xml/HEAD
... 30 more
Caused by: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY003215: could not find writer for content-type application/json type: com.smartling.api.v2.authentication.pto.AuthenticationRequest
at org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.invoke(ManualClosingApacheHttpClient43Engine.java:299)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:492)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:152)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:115)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy13.authenticate(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.smartling.api.v2.client.ExceptionDecoratorInvocationHandler.invoke(ExceptionDecoratorInvocationHandler.java:50)
... 27 more
These are the dependencies I'm using (trying to follow the versions from the SDK and adding as runtime deps what I hoped would help - it didn't, more on this below):
implementation("com.smartling.api:smartling-api-sdk:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.5")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
runtimeOnly("org.jboss.resteasy:resteasy-client:4.6.1.Final")
runtimeOnly("org.glassfish.jersey.core:jersey-client:2.34")
runtimeOnly("org.jboss.resteasy:resteasy-jackson2-provider:4.6.1.Final")
runtimeOnly("org.jboss.resteasy:resteasy-multipart-provider:4.6.1.Final")
runtimeOnly("com.fasterxml.jackson.core:jackson-databind:2.12.3")
runtimeOnly("javax.xml.bind:jaxb-api:2.4.0-b180830.0359")
runtimeOnly("org.jboss.resteasy:resteasy-jaxb-provider:4.6.1.Final")
This is how I create the API client:
val clientFactory = ClientFactory()
val clientConfiguration: ClientConfiguration = DefaultClientConfiguration.builder().build()
val authenticationApi = AuthenticationApiFactory(clientFactory)
.buildApi(clientConfiguration)
val authenticator = Authenticator(userIdentifier, userSecret, authenticationApi)
val bearerAuthSecretFilter = BearerAuthSecretFilter(authenticator)
return FilesApiFactory(clientFactory).buildApi(bearerAuthSecretFilter, clientConfiguration)
And below, how it's used:
smartlingFilesApi.getFileStatus(
projectId,
"$relativePath/$key",
)
Without the additional runtime dependencies, the call to getFileStatus
works, but then a call to downloadTranslatedFile
fails trying to parse XML (as far as I can tell - it does dump the Android strings XML files as the request body in the exception details as well):
Exception in thread "main" com.smartling.api.v2.client.exception.RestApiRuntimeException: http_status=500, method=downloadTranslatedFile, fileUri=foo-bar/src/main/res/values$
at com.smartling.api.v2.client.exception.RestApiExceptionHandler.createRestApiException(RestApiExceptionHandler.java:44)
at com.smartling.api.v2.client.ExceptionDecoratorInvocationHandler.invoke(ExceptionDecoratorInvocationHandler.java:63)
at com.sun.proxy.$Proxy22.downloadTranslatedFile(Unknown Source)
at com.foo.bar.MainKt$downloadFiles$3$1$1.invokeSuspend(Main.kt:338)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
[...]
Caused by: javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: Error during response processing:
type: java.io.InputStream
genericType: class java.io.InputStream
annotations: [
@javax.ws.rs.GET()
@javax.ws.rs.Path(value="/projects/{projectId}/locales/{localeId}/file")
@javax.ws.rs.Produces(value={"*/*"})
]
headers: [Cache-Control=no-cache,Connection=keep-alive,Content-Disposition=attachment; filename="foo-bar/src/main/res/values/strings.xml/HEAD";,Content-T$
media type: application/xml;charset=UTF-8
body: <?xml version="1.0" encoding="UTF-8"?> [here goes the whole XML file]
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:201)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:64)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:154)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:115)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
at com.sun.proxy.$Proxy21.downloadTranslatedFile(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.smartling.api.v2.client.ExceptionDecoratorInvocationHandler.invoke(ExceptionDecoratorInvocationHandler.java:50)
... 10 more
[...]
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/xml;charset=UTF-8 and type class java.io.InputS$
at org.jboss.resteasy.core.interception.jaxrs.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:47)
at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:133)
at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:75)
at com.smartling.api.v2.client.unmarshal.RestApiResponseReaderInterceptor.aroundReadFrom(RestApiResponseReaderInterceptor.java:46)
... 25 more
This is the PTO passed to downloadTranslatedFile
:
DownloadTranslationPTO(
uri, // fileStatus.fileUri, with fileStatus being the response of getFileStatus above
RetrievalType.PUBLISHED,
true,
)
I'm assuming I'm either missing some runtime dependencies or initialisation to add a JSON and/or XML parser to RESTEasy (I'm not familiar with that at all). Is there a set-up part that's not documented/that I missed?