Merge pull request #286 from Verdent/275-class-with-package-private-modif

Fixes #275 Inheriting from class with package level modifier leads to…
diff --git a/src/main/java/org/eclipse/yasson/internal/model/PropertyValuePropagation.java b/src/main/java/org/eclipse/yasson/internal/model/PropertyValuePropagation.java
index 62202b9..77c4ab9 100644
--- a/src/main/java/org/eclipse/yasson/internal/model/PropertyValuePropagation.java
+++ b/src/main/java/org/eclipse/yasson/internal/model/PropertyValuePropagation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,8 +13,6 @@
 
 package org.eclipse.yasson.internal.model;
 
-import org.eclipse.yasson.internal.JsonbContext;
-
 import javax.json.bind.config.PropertyVisibilityStrategy;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
@@ -22,7 +20,6 @@
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Optional;
 import java.util.function.Function;
 
 /**
@@ -116,12 +113,19 @@
         }
         Boolean accessible = isVisible(strategy -> strategy.isVisible(field), field, method);
         //overridden by strategy, or anonymous class (readable by spec)
-        if (accessible && (!Modifier.isPublic(field.getModifiers()) || field.getDeclaringClass().isAnonymousClass())) {
+        if (accessible && (
+                !Modifier.isPublic(field.getModifiers())
+                        || field.getDeclaringClass().isAnonymousClass()
+                        || isNotPublicAndNonNested(field.getDeclaringClass()))) {
             overrideAccessible(field);
         }
         return accessible;
     }
 
+    private boolean isNotPublicAndNonNested(Class<?> declaringClass) {
+        return !declaringClass.isMemberClass() && !Modifier.isPublic(declaringClass.getModifiers());
+    }
+
     private boolean isMethodVisible(Field field, Method method) {
         if (method == null || Modifier.isStatic(method.getModifiers())) {
             return false;
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/ClassModifiersTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/ClassModifiersTest.java
new file mode 100644
index 0000000..bf2a7b4
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/ClassModifiersTest.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * David Kral
+ ******************************************************************************/
+
+package org.eclipse.yasson.defaultmapping.modifiers;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbException;
+
+import org.eclipse.yasson.defaultmapping.modifiers.model.ChildOfPackagePrivateParent;
+import org.eclipse.yasson.defaultmapping.modifiers.model.FieldModifiersClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test access modifiers on classes
+ *
+ * @author David Kral
+ */
+public class ClassModifiersTest {
+
+    private Jsonb jsonb;
+
+    @Before
+    public void before() {
+        jsonb = JsonbBuilder.create();
+    }
+
+    @Test
+    public void testPackagePrivateParent() {
+        ChildOfPackagePrivateParent child = new ChildOfPackagePrivateParent();
+        child.id = 1;
+        child.name = "SomeName";
+        String json = jsonb.toJson(child);
+        assertEquals("{\"id\":1,\"name\":\"SomeName\"}", json);
+        ChildOfPackagePrivateParent result = jsonb.fromJson(json, ChildOfPackagePrivateParent.class);
+        assertEquals(child.id, result.id);
+        assertEquals(child.name, result.name);
+    }
+
+
+    class NestedPackageParent {
+        public int id;
+    }
+
+    public class NestedPackageChild extends NestedPackageParent {
+        public String name;
+    }
+
+    @Test
+    public void testNestedPackagePrivateParent() {
+        NestedPackageChild child = new NestedPackageChild();
+        child.id = 1;
+        child.name = "SomeName";
+        try {
+            jsonb.toJson(child);
+            fail();
+        } catch (JsonbException ex) {
+            if (!(ex.getCause() instanceof IllegalAccessException)) {
+                fail();
+            }
+        }
+    }
+
+    private class NestedPrivateParent {
+        public int id;
+    }
+
+    public class NestedPrivateChild extends NestedPrivateParent {
+        public String name;
+    }
+
+    @Test
+    public void testNestedPrivateParent() {
+        NestedPrivateChild child = new NestedPrivateChild();
+        child.id = 1;
+        child.name = "SomeName";
+        try {
+            jsonb.toJson(child);
+            fail();
+        } catch (JsonbException ex) {
+            if (!(ex.getCause() instanceof IllegalAccessException)) {
+                fail();
+            }
+        }
+    }
+
+
+    static class NestedStaticPackageParent {
+        public int id;
+    }
+
+    public static class NestedStaticPackageChild extends NestedStaticPackageParent {
+        public String name;
+    }
+
+    @Test
+    public void testNestedStaticPackagePrivateParent() {
+        NestedStaticPackageChild child = new NestedStaticPackageChild();
+        child.id = 1;
+        child.name = "SomeName";
+        try {
+            jsonb.toJson(child);
+            fail();
+        } catch (JsonbException ex) {
+            if (!(ex.getCause() instanceof IllegalAccessException)) {
+                fail();
+            }
+        }
+    }
+
+    private static class NestedStaticPrivateParent {
+        public int id;
+    }
+
+    public static class NestedStaticPrivateChild extends NestedStaticPrivateParent {
+        public String name;
+    }
+
+    @Test
+    public void testNestedStaticPrivateParent() {
+        NestedStaticPrivateChild child = new NestedStaticPrivateChild();
+        child.id = 1;
+        child.name = "SomeName";
+        try {
+            jsonb.toJson(child);
+            fail();
+        } catch (JsonbException ex) {
+            if (!(ex.getCause() instanceof IllegalAccessException)) {
+                fail();
+            }
+        }
+    }
+
+}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/ChildOfPackagePrivateParent.java b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/ChildOfPackagePrivateParent.java
new file mode 100644
index 0000000..dd22945
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/ChildOfPackagePrivateParent.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * David Kral
+ ******************************************************************************/
+
+package org.eclipse.yasson.defaultmapping.modifiers.model;
+
+/**
+ * @author David Kral
+ */
+public class ChildOfPackagePrivateParent extends PackagePrivateParent {
+
+    public String name;
+
+}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/PackagePrivateParent.java b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/PackagePrivateParent.java
new file mode 100644
index 0000000..18d051c
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/modifiers/model/PackagePrivateParent.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * David Kral
+ ******************************************************************************/
+
+package org.eclipse.yasson.defaultmapping.modifiers.model;
+
+/**
+ * @author David Kral
+ */
+class PackagePrivateParent {
+
+    public int id;
+
+}