diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ce72f20..6e9796af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: test: docker: - - image: openjdk:11 + - image: openjdk:17 steps: - checkout - run: @@ -17,7 +17,7 @@ jobs: path: test-results deploy: docker: - - image: openjdk:11 + - image: openjdk:17 steps: - add_ssh_keys: fingerprints: @@ -49,4 +49,6 @@ workflows: - test filters: branches: - only: master + only: + - master + - 2.x diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 7d59a01f..17c59992 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.8/apache-maven-3.8.8-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar diff --git a/README.md b/README.md index 798214bd..663f7cda 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,26 @@ Java SDK for integrating with the [Smartling API]. +> **Note**: Version 2.x requires Java 17+. If you need Java 8 compatibility, use version 1.x (maintenance mode). + +## SDK Versions + +We maintain two major versions of this SDK: + +### Version 2.x (Current - Recommended) +- **Branch**: `2.x` +- **Java Compatibility**: Java 17+ +- **Status**: Active development +- **Recommendation**: All new projects should use 2.x. Existing projects are strongly encouraged to migrate. + +### Version 1.x (Maintenance Mode) +- **Branch**: `master` +- **Java Compatibility**: Java 8+ +- **Status**: Maintenance only - critical fixes and security updates +- **Future**: Will be deprecated once migration to 2.x is complete + +We strongly encourage all users to migrate to version 2.x to benefit from modern Java features, improved performance, and continued feature development. Version 1.x will eventually be deprecated as Smartling projects and clients complete their migration. + ## Using this SDK The Smartling API SDK is distributed via Maven Central and is compatible with JDK 1.7 diff --git a/pom.xml b/pom.xml index 099a6504..74e85933 100644 --- a/pom.xml +++ b/pom.xml @@ -26,16 +26,20 @@ UTF-8 UTF-8 - 2.0.4 - 4.6.1.Final + 4.7.10.Final 4.5.14 - 2.12.3 - 4.9.3 - 2.26.0 + 2.17.3 + 4.12.0 + 2.35.2 + + javax.annotation + javax.annotation-api + 1.3.2 + org.apache.httpcomponents httpclient @@ -45,10 +49,15 @@ + + javax.annotation + javax.annotation-api + 1.3.2 + org.projectlombok lombok - 1.18.10 + 1.18.38 provided @@ -79,24 +88,24 @@ org.slf4j slf4j-api - 1.7.28 + 2.0.16 org.slf4j slf4j-simple - 1.7.28 + 2.0.16 provided junit junit - 4.13.1 + 4.13.2 test org.mockito mockito-core - 2.28.2 + 5.18.0 test @@ -107,7 +116,7 @@ com.github.tomakehurst - wiremock + wiremock-jre8 ${wiremock.version} test @@ -118,10 +127,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.13.0 - 1.8 - 1.8 + 17 + 17 -parameters @@ -130,7 +139,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.2.7 --no-tty @@ -152,7 +161,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.11.2 https://docs.oracle.com/javaee/7/api/ @@ -226,7 +235,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5.3 + 3.1.1 true false @@ -241,7 +250,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.1 attach-sources @@ -254,7 +263,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.1 + 3.11.2 attach-javadocs diff --git a/samrtling-api-test-utils/pom.xml b/samrtling-api-test-utils/pom.xml index 178ca9c2..db17a9b3 100644 --- a/samrtling-api-test-utils/pom.xml +++ b/samrtling-api-test-utils/pom.xml @@ -16,8 +16,13 @@ com.github.tomakehurst - wiremock + wiremock-jre8 ${wiremock.version} + + org.apache.commons + commons-lang3 + 3.17.0 + diff --git a/smartling-api-commons/src/main/java/com/smartling/api/v2/client/DefaultClientConfiguration.java b/smartling-api-commons/src/main/java/com/smartling/api/v2/client/DefaultClientConfiguration.java index 02eee8f7..a105901d 100644 --- a/smartling-api-commons/src/main/java/com/smartling/api/v2/client/DefaultClientConfiguration.java +++ b/smartling-api-commons/src/main/java/com/smartling/api/v2/client/DefaultClientConfiguration.java @@ -53,9 +53,12 @@ public class DefaultClientConfiguration implements ClientConfiguration @NonNull private HttpClientConfiguration httpClientConfiguration = new HttpClientConfiguration(); + @Builder.Default private ResteasyProviderFactory resteasyProviderFactory = null; + @Builder.Default private RestApiExceptionMapper exceptionMapper = null; + @Builder.Default private LibNameVersionHolder libNameVersionHolder = null; } diff --git a/smartling-api-commons/src/main/java/com/smartling/api/v2/client/unmarshal/RestApiContextResolver.java b/smartling-api-commons/src/main/java/com/smartling/api/v2/client/unmarshal/RestApiContextResolver.java index e9b5b90c..edc6ade8 100644 --- a/smartling-api-commons/src/main/java/com/smartling/api/v2/client/unmarshal/RestApiContextResolver.java +++ b/smartling-api-commons/src/main/java/com/smartling/api/v2/client/unmarshal/RestApiContextResolver.java @@ -42,7 +42,7 @@ public RestApiContextResolver(final Map, JsonDeserializer> classJson deserializerModule.addSerializer(klass, (JsonSerializer) classJsonSerializerMap.get(klass)); objectMapper.registerModule(deserializerModule); - objectMapper.registerModule(new KotlinModule()); + objectMapper.registerModule(new KotlinModule.Builder().build()); this.objectMapper = objectMapper; } diff --git a/smartling-api-commons/src/main/java/com/smartling/resteasy/ext/ExtendedMultipartFormWriter.java b/smartling-api-commons/src/main/java/com/smartling/resteasy/ext/ExtendedMultipartFormWriter.java index d4b0d12e..fd02770e 100644 --- a/smartling-api-commons/src/main/java/com/smartling/resteasy/ext/ExtendedMultipartFormWriter.java +++ b/smartling-api-commons/src/main/java/com/smartling/resteasy/ext/ExtendedMultipartFormWriter.java @@ -2,7 +2,6 @@ import org.apache.commons.lang3.StringUtils; import org.jboss.resteasy.annotations.providers.multipart.PartType; -import org.jboss.resteasy.plugins.providers.multipart.FieldEnablerPrivilegedAction; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationWriter; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput; import org.jboss.resteasy.spi.WriterException; @@ -12,7 +11,6 @@ import javax.ws.rs.ext.Provider; import java.io.IOException; import java.lang.reflect.Field; -import java.security.AccessController; import java.util.List; import java.util.Map; @@ -39,7 +37,7 @@ protected void getFields(Class type, MultipartFormDataOutput output, Object o { if (field.isAnnotationPresent(DynamicFormParam.class) && field.isAnnotationPresent(PartType.class)) { - AccessController.doPrivileged(new FieldEnablerPrivilegedAction(field)); + field.setAccessible(true); Object value = safeExtractValue(obj, field); @@ -67,7 +65,7 @@ protected void getFields(Class type, MultipartFormDataOutput output, Object o } if (field.isAnnotationPresent(ListFormParam.class) && field.isAnnotationPresent(PartType.class)) { - AccessController.doPrivileged(new FieldEnablerPrivilegedAction(field)); + field.setAccessible(true); Object value = safeExtractValue(obj, field); if (value instanceof List) @@ -88,7 +86,7 @@ protected void getFields(Class type, MultipartFormDataOutput output, Object o } if (field.isAnnotationPresent(FileFormParam.class) && field.isAnnotationPresent(PartType.class)) { - AccessController.doPrivileged(new FieldEnablerPrivilegedAction(field)); + field.setAccessible(true); FileFormParam fileFormParam = field.getAnnotation(FileFormParam.class); String name = fileFormParam.value(); @@ -112,7 +110,7 @@ private String getFilename(Object obj, Field[] declaredFields, Field field) { if (declaredField.getName().equals(filenameField)) { - AccessController.doPrivileged(new FieldEnablerPrivilegedAction(declaredField)); + declaredField.setAccessible(true); return (String) safeExtractValue(obj, declaredField); } diff --git a/smartling-api-commons/src/test/java/com/smartling/api/v2/auth/AuthenticationIntegrationTest.java b/smartling-api-commons/src/test/java/com/smartling/api/v2/auth/AuthenticationIntegrationTest.java index c758e5c1..ee2ac90b 100644 --- a/smartling-api-commons/src/test/java/com/smartling/api/v2/auth/AuthenticationIntegrationTest.java +++ b/smartling-api-commons/src/test/java/com/smartling/api/v2/auth/AuthenticationIntegrationTest.java @@ -133,9 +133,9 @@ public void shouldLogWeirdContentType() "\tgenericType: class com.smartling.api.v2.authentication.pto.Authentication\n" + "\tannotations: [\n" + "\t\t@javax.ws.rs.POST()\n" + - "\t\t@javax.ws.rs.Path(value=\"/authenticate\")\n" + + "\t\t@javax.ws.rs.Path(\"/authenticate\")\n" + "\t]\n" + - "\theaders: [Content-Type=*/*,Matched-Stub-Id=" + stubMapping.getId() + ",Server=Jetty(9.2.28.v20190418),Transfer-Encoding=chunked,Vary=Accept-Encoding, User-Agent]\n" + + "\theaders: [Content-Type=*/*,Matched-Stub-Id=" + stubMapping.getId() + ",Transfer-Encoding=chunked,Vary=Accept-Encoding, User-Agent]\n" + "\tmedia type: */*\n" + "\tbody: {\"response\":{\"code\":\"SUCCESS\",\"data\":{\"accessToken\":\"accessTokenValue\",\"refreshToken\":\"refreshTokenValue\",\"expiresIn\":480,\"refreshExpiresIn\":21600,\"tokenType\":\"Bearer\"}}}"; String actualMessage = null; diff --git a/smartling-api-commons/src/test/java/com/smartling/api/v2/client/unmarshal/DetailsDeserializerTest.java b/smartling-api-commons/src/test/java/com/smartling/api/v2/client/unmarshal/DetailsDeserializerTest.java index 70e03394..99d9337b 100644 --- a/smartling-api-commons/src/test/java/com/smartling/api/v2/client/unmarshal/DetailsDeserializerTest.java +++ b/smartling-api-commons/src/test/java/com/smartling/api/v2/client/unmarshal/DetailsDeserializerTest.java @@ -56,6 +56,7 @@ public void setUp() throws Exception public void testDeserializeNullBody() throws Exception { when(node.getNodeType()).thenReturn(JsonNodeType.NULL); + when(node.isNull()).thenReturn(true); final Details details = detailsDeserializer.deserialize(parser, null); assertNull(details); } diff --git a/smartling-attachments-api/src/test/java/com/smartling/api/attachments/v2/AttachmentsApiTest.java b/smartling-attachments-api/src/test/java/com/smartling/api/attachments/v2/AttachmentsApiTest.java index 1d8b6550..b8ce572f 100644 --- a/smartling-attachments-api/src/test/java/com/smartling/api/attachments/v2/AttachmentsApiTest.java +++ b/smartling-attachments-api/src/test/java/com/smartling/api/attachments/v2/AttachmentsApiTest.java @@ -183,25 +183,25 @@ public void testUploadAttachment() throws Exception "\r\n" + "content\r\n" + partSeparator + "\r\n" + - "Content-Disposition: form-data; name=\"name\"\r\n" + + "Content-Disposition: form-data; name=\"entityUids\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + - "test.txt\r\n" + + "jobUuid1\r\n" + partSeparator + "\r\n" + - "Content-Disposition: form-data; name=\"description\"\r\n" + + "Content-Disposition: form-data; name=\"entityUids\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + - "description\r\n" + + "jobUuid2\r\n" + partSeparator + "\r\n" + - "Content-Disposition: form-data; name=\"entityUids\"\r\n" + + "Content-Disposition: form-data; name=\"name\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + - "jobUuid1\r\n" + + "test.txt\r\n" + partSeparator + "\r\n" + - "Content-Disposition: form-data; name=\"entityUids\"\r\n" + + "Content-Disposition: form-data; name=\"description\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + - "jobUuid2\r\n" + + "description\r\n" + partSeparator + "--"); assertEquals(expectedPTO.getAttachmentUid(), response.getAttachmentUid()); diff --git a/smartling-job-batches-api/src/main/java/com/smartling/api/jobbatches/util/FileUploadProxyUtils.java b/smartling-job-batches-api/src/main/java/com/smartling/api/jobbatches/util/FileUploadProxyUtils.java index 02a9c1df..354e94b3 100644 --- a/smartling-job-batches-api/src/main/java/com/smartling/api/jobbatches/util/FileUploadProxyUtils.java +++ b/smartling-job-batches-api/src/main/java/com/smartling/api/jobbatches/util/FileUploadProxyUtils.java @@ -8,7 +8,6 @@ import org.jboss.resteasy.annotations.providers.multipart.PartType; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.jboss.resteasy.client.jaxrs.internal.ClientResponse; -import org.jboss.resteasy.plugins.providers.multipart.FieldEnablerPrivilegedAction; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput; import javax.ws.rs.FormParam; @@ -21,7 +20,6 @@ import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.security.AccessController; import java.util.Map; @Slf4j @@ -65,7 +63,7 @@ public static void getFields(Class type, MultipartFormDataOutput output, Obje { for (Field field : type.getDeclaredFields()) { - AccessController.doPrivileged(new FieldEnablerPrivilegedAction(field)); + field.setAccessible(true); Object value = getFieldValue(field, obj); if (value == null) {