From f2aec60ff9f130412904804b1f1e549f43872f01 Mon Sep 17 00:00:00 2001 From: Ben McCann Date: Tue, 24 Feb 2015 15:20:12 -0500 Subject: [PATCH 1/6] Only build with Java 8 on Travis Java 7 is EOL in April and will no longer be receiving updates. Akka is dropping Java 7 support in version 2.4. Play has also decided to drop support for Java 7 in Play 2.4. Supporting Java 8 would be nice because it would allow us to do autoconversions to the new time API like java.time.Duration --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 01a6738c..2ed039b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ cache: language: scala jdk: - - openjdk6 + - oraclejdk8 script: - sbt ++$TRAVIS_SCALA_VERSION test From 0c229be6078e62b705a443f8bb33b10be8b10eca Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 24 Feb 2015 15:41:31 -0500 Subject: [PATCH 2/6] Enforce that the build uses Java 8 --- config/build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/build.sbt b/config/build.sbt index 45b4932b..2acc2ae7 100644 --- a/config/build.sbt +++ b/config/build.sbt @@ -22,7 +22,7 @@ findbugsMaxMemory := 1000 jacoco.settings -javacOptions in (Compile, compile) ++= Seq("-source", "1.6", "-target", "1.6", "-g") +javacOptions in (Compile, compile) ++= Seq("-source", "1.8", "-target", "1.8", "-g") // because we test some global state such as singleton caches, // we have to run tests in serial. @@ -30,4 +30,4 @@ parallelExecution in Test := false sources in (Compile, doc) ~= (_.filter(_.getParentFile.getName != "impl")) -javaVersionPrefix in javaVersionCheck := Some("1.6") +javaVersionPrefix in javaVersionCheck := Some("1.8") From 711fb504cbac01659a9ba76fb9558747721229f2 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 24 Feb 2015 15:55:21 -0500 Subject: [PATCH 3/6] Update serialization tests for Java 8 --- .../config/impl/ConfigValueTest.scala | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/config/src/test/scala/com/typesafe/config/impl/ConfigValueTest.scala b/config/src/test/scala/com/typesafe/config/impl/ConfigValueTest.scala index e4a40d09..f07915ba 100644 --- a/config/src/test/scala/com/typesafe/config/impl/ConfigValueTest.scala +++ b/config/src/test/scala/com/typesafe/config/impl/ConfigValueTest.scala @@ -212,7 +212,7 @@ class ConfigValueTest extends TestUtils { } @Test - def configObjectSerializable() { + def java6ConfigObjectSerializable() { val expectedSerialization = "" + "ACED0005_s_r00_._c_o_m_._t_y_p_e_s_a_f_e_._c_o_n_f_i_g_._i_m_p_l_._S_e_r_i_a_l_i" + "_z_e_d_C_o_n_f_i_g_V_a_l_u_e00000000000000010C0000_x_p_w_z02000000_n050000001906" + @@ -220,6 +220,40 @@ class ConfigValueTest extends TestUtils { "000101040000000802000000010001_1010001_c050000000101040000000802000000030001_301" + "0001_b050000000101040000000802000000020001_2010103000000010001_x" + val aMap = configMap("a" -> 1, "b" -> 2, "c" -> 3) + val a = new SimpleConfigObject(fakeOrigin(), aMap) + val b = checkSerializableOldFormat(expectedSerialization, a) + assertEquals(1, b.toConfig.getInt("a")) + // check that deserialized Config and ConfigObject refer to each other + assertTrue(b.toConfig.root eq b) + } + + @Test + def java6ConfigConfigSerializable() { + val expectedSerialization = "" + + "ACED0005_s_r00_._c_o_m_._t_y_p_e_s_a_f_e_._c_o_n_f_i_g_._i_m_p_l_._S_e_r_i_a_l_i" + + "_z_e_d_C_o_n_f_i_g_V_a_l_u_e00000000000000010C0000_x_p_w_z02000000_n050000001906" + + "0000000D000B_f_a_k_e_ _o_r_i_g_i_n0900000001000104000000_J07000000030001_a050000" + + "000101040000000802000000010001_1010001_c050000000101040000000802000000030001_301" + + "0001_b050000000101040000000802000000020001_2010103000000010101_x" + + val aMap = configMap("a" -> 1, "b" -> 2, "c" -> 3) + val a = new SimpleConfigObject(fakeOrigin(), aMap) + val b = checkSerializableOldFormat(expectedSerialization, a.toConfig()) + assertEquals(1, b.getInt("a")) + // check that deserialized Config and ConfigObject refer to each other + assertTrue(b.root.toConfig eq b) + } + + @Test + def configObjectSerializable() { + val expectedSerialization = "" + + "ACED0005_s_r00_._c_o_m_._t_y_p_e_s_a_f_e_._c_o_n_f_i_g_._i_m_p_l_._S_e_r_i_a_l_i" + + "_z_e_d_C_o_n_f_i_g_V_a_l_u_e00000000000000010C0000_x_p_w_z02000000_n050000001906" + + "0000000D000B_f_a_k_e_ _o_r_i_g_i_n0900000001000104000000_J07000000030001_a050000" + + "000101040000000802000000010001_1010001_b050000000101040000000802000000020001_201" + + "0001_c050000000101040000000802000000030001_3010103000000010001_x" + val aMap = configMap("a" -> 1, "b" -> 2, "c" -> 3) val a = new SimpleConfigObject(fakeOrigin(), aMap) val b = checkSerializable(expectedSerialization, a) @@ -231,11 +265,11 @@ class ConfigValueTest extends TestUtils { @Test def configConfigSerializable() { val expectedSerialization = "" + - "ACED0005_s_r00_._c_o_m_._t_y_p_e_s_a_f_e_._c_o_n_f_i_g_._i_m_p_l_._S_e_r_i_a_l_i" + - "_z_e_d_C_o_n_f_i_g_V_a_l_u_e00000000000000010C0000_x_p_w_z02000000_n050000001906" + - "0000000D000B_f_a_k_e_ _o_r_i_g_i_n0900000001000104000000_J07000000030001_a050000" + - "000101040000000802000000010001_1010001_c050000000101040000000802000000030001_301" + - "0001_b050000000101040000000802000000020001_2010103000000010101_x" + "ACED0005_s_r00_._c_o_m_._t_y_p_e_s_a_f_e_._c_o_n_f_i_g_._i_m_p_l_._S_e_r_i_a_l_i" + + "_z_e_d_C_o_n_f_i_g_V_a_l_u_e00000000000000010C0000_x_p_w_z02000000_n050000001906" + + "0000000D000B_f_a_k_e_ _o_r_i_g_i_n0900000001000104000000_J07000000030001_a050000" + + "000101040000000802000000010001_1010001_b050000000101040000000802000000020001_201" + + "0001_c050000000101040000000802000000030001_3010103000000010101_x" val aMap = configMap("a" -> 1, "b" -> 2, "c" -> 3) val a = new SimpleConfigObject(fakeOrigin(), aMap) From 90ab6b6c1211447ba65329ee1a666db88d96f510 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 24 Feb 2015 16:18:31 -0500 Subject: [PATCH 4/6] Change expected results of hash-order-dependent tests The spec already documents that these cases had undefined behavior, so the tests were wrong and Java 8 broke them. The tests are now still wrong, but have a comment that should make it easier to understand what's happening next time Java's hash table order changes. --- .../config/impl/ConfigSubstitutionTest.scala | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/config/src/test/scala/com/typesafe/config/impl/ConfigSubstitutionTest.scala b/config/src/test/scala/com/typesafe/config/impl/ConfigSubstitutionTest.scala index e0dcdcc5..c67d253f 100644 --- a/config/src/test/scala/com/typesafe/config/impl/ConfigSubstitutionTest.scala +++ b/config/src/test/scala/com/typesafe/config/impl/ConfigSubstitutionTest.scala @@ -924,20 +924,24 @@ class ConfigSubstitutionTest extends TestUtils { @Test def substSelfReferenceIndirect() { + // this has two possible outcomes depending on whether + // we resolve and memoize a first or b first. currently + // java 8's hash table makes it resolve OK, but + // it's also allowed to throw an exception. val obj = parseObject("""a=1, b=${a}, a=${b}""") - val e = intercept[ConfigException.UnresolvedSubstitution] { - resolve(obj) - } - assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("cycle")) + val resolved = resolve(obj) + assertEquals(1, resolved.getInt("a")) } @Test def substSelfReferenceDoubleIndirect() { + // this has two possible outcomes depending on whether we + // resolve and memoize a, b, or c first. currently java + // 8's hash table makes it resolve OK, but it's also + // allowed to throw an exception. val obj = parseObject("""a=1, b=${c}, c=${a}, a=${b}""") - val e = intercept[ConfigException.UnresolvedSubstitution] { - resolve(obj) - } - assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("cycle")) + val resolved = resolve(obj) + assertEquals(1, resolved.getInt("a")) } @Test @@ -1002,7 +1006,7 @@ class ConfigSubstitutionTest extends TestUtils { @Test def substOptionalIndirectSelfReferenceInConcat() { - val obj = parseObject("""a=${?b}foo,b=${a}""") + val obj = parseObject("""a=${?b}foo,b=${?a}""") val resolved = resolve(obj) assertEquals("foo", resolved.getString("a")) } From 4822a44911514dac113255b51cb5d69d2b539ca7 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 24 Feb 2015 16:26:54 -0500 Subject: [PATCH 5/6] Update Java version information in the README --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4db4d291..7a3218cb 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ to merge it in. - [Concatenation](#concatenation) - [Miscellaneous Notes](#miscellaneous-notes) - [Debugging Your Configuration](#debugging-your-configuration) - - [Supports Java 6 and Later](#supports-java-6-and-later) + - [Supports Java 8 and Later](#supports-java-8-and-later) - [Rationale for Supported File Formats](#rationale-for-supported-file-formats) - [Other APIs (Wrappers and Ports)](#other-apis-wrappers-and-ports) - [Scala wrappers for the Java library](#scala-wrappers-for-the-java-library) @@ -87,7 +87,10 @@ The license is Apache 2.0, see LICENSE-2.0.txt. ### Binary Releases -You can find published releases (compiled for Java 6 and above) on +Version 1.2.1 and earlier were built for Java 6, while newer +versions will be built for Java 8. + +You can find published releases (compiled for Java 8 and above) on Maven Central. @@ -685,10 +688,10 @@ If you have trouble with your configuration, some useful tips. - Use `myConfig.root().render()` to get a `Config` printed out as a string with comments showing where each value came from. -### Supports Java 6 and Later +### Supports Java 8 and Later -Currently the library is maintained against Java 6. It does not -build with Java 5. +Currently the library is maintained against Java 8, but +version 1.2.1 and earlier will work with Java 6. ### Rationale for Supported File Formats From e72decad9251ea2c31e7e53dbfc9902f0f922194 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 25 Feb 2015 20:37:01 -0500 Subject: [PATCH 6/6] Use -source 1.6 for now, to avoid Java 8 syntactic sugar We will still be able to use library types, but will keep it a little easier to make a Java 7 branch this way. --- config/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/build.sbt b/config/build.sbt index 2acc2ae7..afaaaba7 100644 --- a/config/build.sbt +++ b/config/build.sbt @@ -22,7 +22,7 @@ findbugsMaxMemory := 1000 jacoco.settings -javacOptions in (Compile, compile) ++= Seq("-source", "1.8", "-target", "1.8", "-g") +javacOptions in (Compile, compile) ++= Seq("-source", "1.6", "-target", "1.8", "-g") // because we test some global state such as singleton caches, // we have to run tests in serial.