diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac5a9f39d9..ecbcc2710b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,6 +17,7 @@ jobs: - java: 11 upload_reports: true - java: 17 + fail-fast: false steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: @@ -30,6 +31,10 @@ jobs: - uses: gradle/gradle-build-action@842c587ad8aa4c68eeba24c396e15af4c2e9f30a # v2.9.0 with: arguments: build + - name: Test minified JAR + uses: gradle/gradle-build-action@842c587ad8aa4c68eeba24c396e15af4c2e9f30a # v2.9.0 + with: + arguments: minifyTest - run: ./ion-test-driver-run version - if: ${{ matrix.upload_reports }} uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 diff --git a/THIRD_PARTY_LICENSES.md b/THIRD_PARTY_LICENSES.md new file mode 100644 index 0000000000..73629fbdc9 --- /dev/null +++ b/THIRD_PARTY_LICENSES.md @@ -0,0 +1,17 @@ + +# ion-java +## Dependency License Report + +## Apache License, Version 2.0 + +**1** **Group:** `org.jetbrains` **Name:** `annotations` **Version:** `13.0` +> - **POM Project URL**: [http://www.jetbrains.org](http://www.jetbrains.org) +> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) + +**2** **Group:** `org.jetbrains.kotlin` **Name:** `kotlin-stdlib` **Version:** `1.9.0` +> - **POM Project URL**: [https://kotlinlang.org/](https://kotlinlang.org/) +> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) + +**3** **Group:** `org.jetbrains.kotlin` **Name:** `kotlin-stdlib-common` **Version:** `1.9.0` +> - **POM Project URL**: [https://kotlinlang.org/](https://kotlinlang.org/) +> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) diff --git a/build.gradle.kts b/build.gradle.kts index ec8459fdbf..026e0840de 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,38 @@ +import com.github.jk1.license.filter.LicenseBundleNormalizer +import com.github.jk1.license.render.InventoryMarkdownReportRenderer +import com.github.jk1.license.render.TextReportRenderer +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions +import proguard.gradle.ProGuardTask import java.net.URI import java.time.Instant import java.util.Properties +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("com.guardsquare:proguard-gradle:7.4.0") + } +} plugins { + kotlin("jvm") version "1.9.0" java `maven-publish` jacoco signing + id("com.github.johnrengelman.shadow") version "8.1.1" + id("org.cyclonedx.bom") version "1.7.2" id("com.github.spotbugs") version "5.0.13" + id("org.jlleitschuh.gradle.ktlint") version "11.3.2" // TODO: more static analysis. E.g.: // id("com.diffplug.spotless") version "6.11.0" + + // Used for generating the third party attribution document + id("com.github.jk1.dependency-license-report") version "2.5" } jacoco { @@ -20,9 +41,12 @@ jacoco { repositories { mavenCentral() + google() } dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.7.1") testCompileOnly("junit:junit:4.13") testRuntimeOnly("org.junit.vintage:junit-vintage-engine") @@ -38,20 +62,38 @@ version = File(project.rootDir.path + "/project.version").readLines().single() description = "A Java implementation of the Amazon Ion data notation." val isReleaseVersion: Boolean = !version.toString().endsWith("SNAPSHOT") -val generatedJarInfoDir = "${buildDir}/generated/jar-info" +val generatedResourcesDir = "$buildDir/generated/main/resources" lateinit var sourcesArtifact: PublishArtifact lateinit var javadocArtifact: PublishArtifact sourceSets { main { java.srcDir("src") - resources.srcDir(generatedJarInfoDir) + resources.srcDir(generatedResourcesDir) } test { java.srcDir("test") } } +licenseReport { + // Because of the current gradle project structure, we must explicitly exclude ion-java-cli, even + // though ion-java does not depend on ion-java-cli. By default, the license report generator includes + // the current project (ion-java) and all its subprojects. + projects = arrayOf(project) + outputDir = "$buildDir/reports/licenses" + renderers = arrayOf(InventoryMarkdownReportRenderer(), TextReportRenderer()) + // Dependencies use inconsistent titles for Apache-2.0, so we need to specify mappings + filters = arrayOf( + LicenseBundleNormalizer( + mapOf( + "The Apache License, Version 2.0" to "Apache-2.0", + "The Apache Software License, Version 2.0" to "Apache-2.0", + ) + ) + ) +} + tasks { withType { options.encoding = "UTF-8" @@ -59,6 +101,116 @@ tasks { // emit JDK 8 compatible classes due to widespread use of this library with JDK 8. options.release.set(8) } + withType> { + kotlinOptions { + // Kotlin jvmTarget must match the JavaCompile release version + jvmTarget = "1.8" + } + } + + jar { + archiveClassifier.set("original") + } + + // Creates a super jar of ion-java and its dependencies where all dependencies are shaded (moved) + // to com.amazon.ion_.shaded.are_you_sure_you_want_to_use_this + shadowJar { + val newLocation = "com.amazon.ion.shaded_.do_not_use" + archiveClassifier.set("shaded") + dependsOn(generateLicenseReport) + from(generateLicenseReport.get().outputFolder) + relocate("kotlin", "$newLocation.kotlin") + relocate("org.jetbrains", "$newLocation.org.jetbrains") + relocate("org.intellij", "$newLocation.org.intellij") + dependencies { + // Remove all Kotlin metadata so that it looks like an ordinary Java Jar + exclude("**/*.kotlin_metadata") + exclude("**/*.kotlin_module") + exclude("**/*.kotlin_builtins") + // Eliminate dependencies' pom files + exclude("**/pom.*") + } + } + + /** + * The `minifyJar` task uses Proguard to create a JAR that is smaller than the combined size of ion-java + * and its dependencies. This is the final JAR that is published to maven central. + */ + val minifyJar by register("minifyJar") { + group = "build" + val rulesPath = file("config/proguard/rules.pro") + val inputJarPath = shadowJar.get().outputs.files.singleFile + val outputJarPath = "build/libs/ion-java-$version.jar" + + inputs.file(rulesPath) + inputs.file(inputJarPath) + outputs.file(outputJarPath) + dependsOn(shadowJar) + dependsOn(configurations.runtimeClasspath) + + injars(inputJarPath) + outjars(outputJarPath) + configuration(rulesPath) + + val javaHome = System.getProperty("java.home") + // Automatically handle the Java version of this build, but we don't support lower than JDK 11 + // See https://github.com/Guardsquare/proguard/blob/e76e47953f6f295350a3bb7eeb801b33aac34eae/examples/gradle-kotlin-dsl/build.gradle.kts#L48-L60 + libraryjars( + mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), + "$javaHome/jmods/java.base.jmod" + ) + } + + build { + dependsOn(minifyJar) + } + + generateLicenseReport { + doLast { + // We don't want the time in the generated markdown report because that makes it unstable for + // our verification of the THIRD_PARTY_LICENSES file. + val markdownReport = outputs.files.single().walk().single { it.path.endsWith(".md") } + val dateRegex = Regex("^_\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} \\w+_$") + // Reads the content of the markdown report, replacing the date line with an empty line, and + // trimming extra whitespace from the end of all other lines. + val newMarkdownContent = markdownReport.readLines() + .joinToString("\n") { if (it.matches(dateRegex)) "" else it.trimEnd() } + markdownReport.writeText(newMarkdownContent) + } + } + + // Task to check whether the THIRD_PARTY_LICENSES file is still up-to-date. + val checkThirdPartyLicensesFile by register("checkThirdPartyLicensesFile") { + val thirdPartyLicensesFileName = "THIRD_PARTY_LICENSES.md" + val thirdPartyLicensesPath = "$rootDir/$thirdPartyLicensesFileName" + dependsOn(generateLicenseReport) + inputs.file(thirdPartyLicensesPath) + group = "verification" + description = "Verifies that $thirdPartyLicensesFileName is up-to-date." + doLast { + val generatedMarkdownReport = generateLicenseReport.get().outputs.files.single() + .walk().single { it.path.endsWith(".md") } + val generatedMarkdownReportContent = generatedMarkdownReport.readLines() + .filter { it.isNotBlank() } + .joinToString("\n") + + val sourceControlledMarkdownReport = File(thirdPartyLicensesPath) + val sourceControlledMarkdownReportContent = sourceControlledMarkdownReport.readLines() + .filter { it.isNotBlank() } + .joinToString("\n") + + if (sourceControlledMarkdownReportContent != generatedMarkdownReportContent) { + throw IllegalStateException( + "$thirdPartyLicensesPath is out of date.\n" + + "Please replace the file content with the content of $generatedMarkdownReport." + ) + } + } + } + + check { + dependsOn(checkThirdPartyLicensesFile) + } javadoc { // Suppressing Javadoc warnings is clunky, but there doesn't seem to be any nicer way to do it. @@ -72,6 +224,11 @@ tasks { } } + ktlint { + version.set("0.40.0") + outputToConsole.set(true) + } + // spotbugs-gradle-plugin creates a :spotbugsTest task by default, but we don't want it // see: https://github.com/spotbugs/spotbugs-gradle-plugin/issues/391 project.gradle.startParameter.excludedTaskNames.add(":spotbugsTest") @@ -110,7 +267,7 @@ tasks { "xsltproc", "--output", spotbugsBaselineFile, "$rootDir/config/spotbugs/baseline.xslt", - outputLocation.get().toString() + "${outputLocation.get()}/spotBugs" ) } } @@ -136,15 +293,15 @@ tasks { * for why this is done with a properties file rather than the Jar manifest. */ val generateJarInfo by creating { + val propertiesFile = File("$generatedResourcesDir/${project.name}.properties") doLast { - val propertiesFile = File("$generatedJarInfoDir/${project.name}.properties") propertiesFile.parentFile.mkdirs() val properties = Properties() properties.setProperty("build.version", version.toString()) properties.setProperty("build.time", Instant.now().toString()) properties.store(propertiesFile.writer(), null) } - outputs.dir(generatedJarInfoDir) + outputs.file(propertiesFile) } processResources { dependsOn(generateJarInfo) } @@ -160,7 +317,8 @@ tasks { } } - test { + fun Test.applyCommonTestConfig() { + group = "verification" maxHeapSize = "1g" // When this line was added Xmx 512m was the default, and we saw OOMs maxParallelForks = Math.max(1, Runtime.getRuntime().availableProcessors() / 2) useJUnitPlatform() @@ -168,6 +326,24 @@ tasks { finalizedBy(jacocoTestReport) } + test { + applyCommonTestConfig() + } + + /** Runs the JUnit test on the minified jar. */ + register("minifyTest") { + applyCommonTestConfig() + classpath = project.configurations.testRuntimeClasspath.get() + project.sourceSets.test.get().output + minifyJar.outputs.files + dependsOn(minifyJar) + } + + /** Runs the JUnit test on the shadow jar. */ + register("shadowTest") { + applyCommonTestConfig() + classpath = project.configurations.testRuntimeClasspath.get() + project.sourceSets.test.get().output + shadowJar.get().outputs.files + dependsOn(minifyJar) + } + withType { setOnlyIf { isReleaseVersion && gradle.taskGraph.hasTask(":publish") } } diff --git a/config/proguard/rules.pro b/config/proguard/rules.pro new file mode 100644 index 0000000000..e8657b4dc5 --- /dev/null +++ b/config/proguard/rules.pro @@ -0,0 +1,6 @@ +# See https://www.guardsquare.com/manual/configuration/usage +-keep class !com.amazon.ion.shaded_.** { *; } +-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod +-dontoptimize +-dontobfuscate +-dontwarn java.sql.Timestamp diff --git a/src/com/amazon/ion/impl/IonIteratorImpl.java b/src/com/amazon/ion/impl/IonIteratorImpl.java deleted file mode 100644 index 2083575f07..0000000000 --- a/src/com/amazon/ion/impl/IonIteratorImpl.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2007-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.ion.impl; - -import com.amazon.ion.IonLob; -import com.amazon.ion.IonReader; -import com.amazon.ion.IonSequence; -import com.amazon.ion.IonStruct; -import com.amazon.ion.IonType; -import com.amazon.ion.IonValue; -import com.amazon.ion.SymbolTable; -import com.amazon.ion.SymbolToken; -import com.amazon.ion.ValueFactory; -import java.util.Iterator; -import java.util.NoSuchElementException; - - -final class IonIteratorImpl - implements Iterator -{ - private final ValueFactory _valueFactory; - private final IonReader _reader; - private boolean _at_eof; - private IonValue _curr; - private IonValue _next; - - - - /** - * @throws NullPointerException if any parameter is null. - */ - public IonIteratorImpl(ValueFactory valueFactory, - IonReader input) - { - if (valueFactory == null || input == null) - { - throw new NullPointerException(); - } - - _valueFactory = valueFactory; - _reader = input; - } - - - /** - * Returns true if the iteration has more elements. - * here we actually walk ahead and get the next value (it's - * the only way we know if there are more and clear out the - * various $ion noise out of the way - */ - public boolean hasNext() { - if (_at_eof) return false; - if (_next != null) return true; - return (prefetch() != null); - } - - private IonValue prefetch() - { - assert !_at_eof && _next == null; - - IonType type = _reader.next(); - if (type == null) - { - _at_eof = true; - } - else - { - _next = readValue(); - } - - return _next; - } - - - private IonValue readValue() - { - IonType type = _reader.getType(); - - SymbolToken[] annotations = _reader.getTypeAnnotationSymbols(); - - IonValue v; - - if (_reader.isNullValue()) - { - v = _valueFactory.newNull(type); - } - else - { - switch (type) { - case NULL: - // Handled above - throw new IllegalStateException(); - case BOOL: - v = _valueFactory.newBool(_reader.booleanValue()); - break; - case INT: - v = _valueFactory.newInt(_reader.bigIntegerValue()); - break; - case FLOAT: - v = _valueFactory.newFloat(_reader.doubleValue()); - break; - case DECIMAL: - v = _valueFactory.newDecimal(_reader.decimalValue()); - break; - case TIMESTAMP: - v = _valueFactory.newTimestamp(_reader.timestampValue()); - break; - case STRING: - v = _valueFactory.newString(_reader.stringValue()); - break; - case SYMBOL: - // TODO always pass the SID? Is it correct? - v = _valueFactory.newSymbol(_reader.symbolValue()); - break; - case BLOB: - { - IonLob lob = _valueFactory.newNullBlob(); - lob.setBytes(_reader.newBytes()); - v = lob; - break; - } - case CLOB: - { - IonLob lob = _valueFactory.newNullClob(); - lob.setBytes(_reader.newBytes()); - v = lob; - break; - } - case STRUCT: - { - IonStruct struct = _valueFactory.newEmptyStruct(); - _reader.stepIn(); - while (_reader.next() != null) - { - SymbolToken name = _reader.getFieldNameSymbol(); - IonValue child = readValue(); - struct.add(name, child); - } - _reader.stepOut(); - v = struct; - break; - } - case LIST: - { - IonSequence seq = _valueFactory.newEmptyList(); - _reader.stepIn(); - while (_reader.next() != null) - { - IonValue child = readValue(); - seq.add(child); - } - _reader.stepOut(); - v = seq; - break; - } - case SEXP: - { - IonSequence seq = _valueFactory.newEmptySexp(); - _reader.stepIn(); - while (_reader.next() != null) - { - IonValue child = readValue(); - seq.add(child); - } - _reader.stepOut(); - v = seq; - break; - } - default: - throw new IllegalStateException(); - } - } - - // TODO this is too late in the case of system reading - // when v is a local symtab (it will get itself, not the prior symtab) - SymbolTable symtab = _reader.getSymbolTable(); - ((_Private_IonValue)v).setSymbolTable(symtab); - - if (annotations.length != 0) { - ((_Private_IonValue)v).setTypeAnnotationSymbols(annotations); - } - - return v; - } - - - public IonValue next() { - if (! _at_eof) { - _curr = null; - if (_next == null) { - prefetch(); - } - if (_next != null) { - _curr = _next; - _next = null; - return _curr; - } - } - throw new NoSuchElementException(); - } - - - public void remove() { - throw new UnsupportedOperationException(); - } -} diff --git a/src/com/amazon/ion/impl/IonIteratorImpl.kt b/src/com/amazon/ion/impl/IonIteratorImpl.kt new file mode 100644 index 0000000000..33ec4c6793 --- /dev/null +++ b/src/com/amazon/ion/impl/IonIteratorImpl.kt @@ -0,0 +1,99 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.amazon.ion.impl + +import com.amazon.ion.IonReader +import com.amazon.ion.IonType +import com.amazon.ion.IonValue +import com.amazon.ion.ValueFactory + +/** + * An [Iterator] that wraps an [IonReader] and emits [IonValue]s. + */ +internal class IonIteratorImpl(private val _valueFactory: ValueFactory, private val _reader: IonReader) : MutableIterator { + + private var _at_eof = false + private var _next: IonValue? = null + + /** + * Returns true if the iteration has more elements. + * here we actually walk ahead and get the next value (it's + * the only way we know if there are more and clear out the + * various $ion noise out of the way + */ + override fun hasNext(): Boolean { + if (_at_eof) return false + return if (_next != null) true else prefetch() != null + } + + private fun prefetch(): IonValue? { + assert(!_at_eof && _next == null) + val type = _reader.next() + if (type == null) { + _at_eof = true + } else { + _next = readValue() + } + return _next + } + + private fun readValue(): IonValue { + val annotations = _reader.typeAnnotationSymbols + val v = if (_reader.isNullValue) { + _valueFactory.newNull(_reader.type) + } else { + when (_reader.type) { + IonType.NULL -> throw IllegalStateException() + IonType.BOOL -> _valueFactory.newBool(_reader.booleanValue()) + IonType.INT -> _valueFactory.newInt(_reader.bigIntegerValue()) + IonType.FLOAT -> _valueFactory.newFloat(_reader.doubleValue()) + IonType.DECIMAL -> _valueFactory.newDecimal(_reader.decimalValue()) + IonType.TIMESTAMP -> _valueFactory.newTimestamp(_reader.timestampValue()) + IonType.STRING -> _valueFactory.newString(_reader.stringValue()) + // TODO always pass the SID? Is it correct? + IonType.SYMBOL -> _valueFactory.newSymbol(_reader.symbolValue()) + IonType.BLOB -> _valueFactory.newNullBlob().apply { bytes = _reader.newBytes() } + IonType.CLOB -> _valueFactory.newNullClob().apply { bytes = _reader.newBytes() } + IonType.STRUCT -> _valueFactory.newEmptyStruct().apply { _reader.forEachInContainer { add(fieldNameSymbol, readValue()) } } + IonType.LIST -> _valueFactory.newEmptyList().apply { _reader.forEachInContainer { add(readValue()) } } + IonType.SEXP -> _valueFactory.newEmptySexp().apply { _reader.forEachInContainer { add(readValue()) } } + else -> throw IllegalStateException() + } + } + + // TODO this is too late in the case of system reading + // when v is a local symtab (it will get itself, not the prior symtab) + (v as _Private_IonValue).symbolTable = _reader.symbolTable + if (annotations.isNotEmpty()) v.setTypeAnnotationSymbols(*annotations) + return v + } + + override fun next(): IonValue { + if (_at_eof) throw NoSuchElementException() + val value = _next ?: prefetch() + _next = null + return value ?: throw NoSuchElementException() + } + + override fun remove() { + throw UnsupportedOperationException() + } + + private inline fun IonReader.forEachInContainer(block: IonReader.() -> Unit) { + stepIn() + while (next() != null) { block() } + stepOut() + } +} diff --git a/src/com/amazon/ion/impl/IonReaderTreeUserX.java b/src/com/amazon/ion/impl/IonReaderTreeUserX.java index be70bc2d09..6977da27a6 100644 --- a/src/com/amazon/ion/impl/IonReaderTreeUserX.java +++ b/src/com/amazon/ion/impl/IonReaderTreeUserX.java @@ -21,7 +21,6 @@ import com.amazon.ion.IonCatalog; import com.amazon.ion.IonDatagram; -import com.amazon.ion.IonReader; import com.amazon.ion.IonStruct; import com.amazon.ion.IonSymbol; import com.amazon.ion.IonType; diff --git a/src/com/amazon/ion/impl/IonWriterUser.java b/src/com/amazon/ion/impl/IonWriterUser.java index 60270d510c..b620821fb3 100644 --- a/src/com/amazon/ion/impl/IonWriterUser.java +++ b/src/com/amazon/ion/impl/IonWriterUser.java @@ -16,7 +16,6 @@ package com.amazon.ion.impl; import static com.amazon.ion.SystemSymbols.ION_SYMBOL_TABLE; -import static com.amazon.ion.SystemSymbols.ION_SYMBOL_TABLE_SID; import com.amazon.ion.IonCatalog; import com.amazon.ion.IonException; diff --git a/src/com/amazon/ion/impl/LocalSymbolTable.java b/src/com/amazon/ion/impl/LocalSymbolTable.java index cc6ca89497..713d8998ae 100644 --- a/src/com/amazon/ion/impl/LocalSymbolTable.java +++ b/src/com/amazon/ion/impl/LocalSymbolTable.java @@ -38,7 +38,6 @@ import com.amazon.ion.util.IonTextUtils; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; diff --git a/src/com/amazon/ion/impl/_Private_IonReaderBuilder.java b/src/com/amazon/ion/impl/_Private_IonReaderBuilder.java index 17834a0bc0..c7e56f8abd 100644 --- a/src/com/amazon/ion/impl/_Private_IonReaderBuilder.java +++ b/src/com/amazon/ion/impl/_Private_IonReaderBuilder.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.io.SequenceInputStream; import java.util.zip.GZIPInputStream; import static com.amazon.ion.impl.LocalSymbolTable.DEFAULT_LST_FACTORY; diff --git a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java index e5bda78333..3a12179548 100644 --- a/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java +++ b/src/com/amazon/ion/impl/bin/IonRawBinaryWriter.java @@ -57,6 +57,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.NoSuchElementException; /** diff --git a/src/com/amazon/ion/impl/lite/IonSequenceLite.java b/src/com/amazon/ion/impl/lite/IonSequenceLite.java index 33070838ab..5f58355a36 100644 --- a/src/com/amazon/ion/impl/lite/IonSequenceLite.java +++ b/src/com/amazon/ion/impl/lite/IonSequenceLite.java @@ -17,13 +17,11 @@ import com.amazon.ion.ContainedValueException; import com.amazon.ion.IonSequence; -import com.amazon.ion.IonType; import com.amazon.ion.IonValue; -import com.amazon.ion.IonWriter; import com.amazon.ion.ValueFactory; import com.amazon.ion.impl._Private_CurriedValueFactory; import com.amazon.ion.impl._Private_IonValue; -import java.io.IOException; + import java.lang.reflect.Array; import java.util.AbstractList; import java.util.ArrayList; diff --git a/src/com/amazon/ion/impl/lite/IonStructLite.java b/src/com/amazon/ion/impl/lite/IonStructLite.java index c6ea1fca9a..23344a7497 100644 --- a/src/com/amazon/ion/impl/lite/IonStructLite.java +++ b/src/com/amazon/ion/impl/lite/IonStructLite.java @@ -19,20 +19,17 @@ import com.amazon.ion.IonStruct; import com.amazon.ion.IonType; import com.amazon.ion.IonValue; -import com.amazon.ion.IonWriter; import com.amazon.ion.SymbolToken; import com.amazon.ion.ValueFactory; import com.amazon.ion.ValueVisitor; import com.amazon.ion.impl._Private_CurriedValueFactory; -import com.amazon.ion.util.Equivalence; import com.amazon.ion.UnknownSymbolException; -import java.io.IOException; + import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; diff --git a/src/com/amazon/ion/util/JarInfo.java b/src/com/amazon/ion/util/JarInfo.java index d7e0f3abea..2e00b58162 100644 --- a/src/com/amazon/ion/util/JarInfo.java +++ b/src/com/amazon/ion/util/JarInfo.java @@ -17,13 +17,8 @@ import java.io.IOException; import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; import java.util.Properties; -import java.util.jar.Attributes; -import java.util.jar.Manifest; + import com.amazon.ion.IonException; import com.amazon.ion.Timestamp; diff --git a/test/com/amazon/ion/BinaryReaderSystemProcessingTest.java b/test/com/amazon/ion/BinaryReaderSystemProcessingTest.java index a332d0462b..c9798c5a57 100644 --- a/test/com/amazon/ion/BinaryReaderSystemProcessingTest.java +++ b/test/com/amazon/ion/BinaryReaderSystemProcessingTest.java @@ -20,7 +20,6 @@ import java.math.BigDecimal; import java.math.BigInteger; -import java.util.Date; import static com.amazon.ion.SystemSymbols.ION_1_0; import static com.amazon.ion.SystemSymbols.ION_1_0_SID; diff --git a/test/com/amazon/ion/BinaryTest.java b/test/com/amazon/ion/BinaryTest.java index 5cfe3d6995..4df0e6534f 100644 --- a/test/com/amazon/ion/BinaryTest.java +++ b/test/com/amazon/ion/BinaryTest.java @@ -17,9 +17,7 @@ import static com.amazon.ion.SystemSymbols.ION_SYMBOL_TABLE_SID; -import java.io.IOException; import java.util.Arrays; -import java.util.Iterator; import org.junit.Test; diff --git a/test/com/amazon/ion/BlobTest.java b/test/com/amazon/ion/BlobTest.java index f39fcc210b..035c9160aa 100644 --- a/test/com/amazon/ion/BlobTest.java +++ b/test/com/amazon/ion/BlobTest.java @@ -16,7 +16,7 @@ package com.amazon.ion; import static com.amazon.ion.TestUtils.US_ASCII_CHARSET; -import static com.amazon.ion.impl._Private_Utils.encode; + import com.amazon.ion.impl._Private_Utils; import java.io.IOException; import java.io.InputStream; diff --git a/test/com/amazon/ion/IonTestCase.java b/test/com/amazon/ion/IonTestCase.java index 7158341d59..9b3d915092 100644 --- a/test/com/amazon/ion/IonTestCase.java +++ b/test/com/amazon/ion/IonTestCase.java @@ -26,7 +26,6 @@ import com.amazon.ion.system.IonSystemBuilder; import com.amazon.ion.system.SimpleCatalog; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; diff --git a/test/com/amazon/ion/IonValueTest.java b/test/com/amazon/ion/IonValueTest.java index 38fdb7f0fe..0cac74c1cd 100644 --- a/test/com/amazon/ion/IonValueTest.java +++ b/test/com/amazon/ion/IonValueTest.java @@ -28,8 +28,6 @@ import org.junit.Test; import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; diff --git a/test/com/amazon/ion/StructTest.java b/test/com/amazon/ion/StructTest.java index 6fa84f7773..15cd31fb54 100644 --- a/test/com/amazon/ion/StructTest.java +++ b/test/com/amazon/ion/StructTest.java @@ -28,7 +28,6 @@ import java.util.ListIterator; import java.util.Random; -import com.amazon.ion.system.IonSystemBuilder; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/test/com/amazon/ion/impl/BinaryWriterTest.java b/test/com/amazon/ion/impl/BinaryWriterTest.java index cf4b910bf1..d5ecdc034a 100644 --- a/test/com/amazon/ion/impl/BinaryWriterTest.java +++ b/test/com/amazon/ion/impl/BinaryWriterTest.java @@ -15,7 +15,6 @@ package com.amazon.ion.impl; -import com.amazon.ion.IonCatalog; import com.amazon.ion.IonException; import com.amazon.ion.IonReader; import com.amazon.ion.IonType; diff --git a/test/com/amazon/ion/impl/IonReaderBinaryRawStringTest.java b/test/com/amazon/ion/impl/IonReaderBinaryRawStringTest.java index 3ad6e86938..30ba4cfe8e 100644 --- a/test/com/amazon/ion/impl/IonReaderBinaryRawStringTest.java +++ b/test/com/amazon/ion/impl/IonReaderBinaryRawStringTest.java @@ -1,21 +1,13 @@ package com.amazon.ion.impl; import com.amazon.ion.IonReader; -import com.amazon.ion.IonType; import com.amazon.ion.IonWriter; -import com.amazon.ion.Timestamp; import com.amazon.ion.system.IonBinaryWriterBuilder; import com.amazon.ion.system.IonReaderBuilder; -import com.amazon.ion.util.RepeatInputStream; import org.junit.Test; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.SequenceInputStream; -import java.math.BigDecimal; -import static com.amazon.ion.impl._Private_IonConstants.BINARY_VERSION_MARKER_1_0; import static org.junit.Assert.assertEquals; public class IonReaderBinaryRawStringTest { diff --git a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java index 695cd86d72..57a9d8c2ff 100644 --- a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java +++ b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java @@ -4,8 +4,6 @@ package com.amazon.ion.impl; import com.amazon.ion.BufferConfiguration; -import com.amazon.ion.Decimal; -import com.amazon.ion.IntegerSize; import com.amazon.ion.IonBufferConfiguration; import com.amazon.ion.IonDatagram; import com.amazon.ion.IonException; @@ -22,7 +20,6 @@ import com.amazon.ion.SymbolToken; import com.amazon.ion.SystemSymbols; import com.amazon.ion.TestUtils; -import com.amazon.ion.Timestamp; import com.amazon.ion.UnknownSymbolException; import com.amazon.ion.impl.bin._Private_IonManagedBinaryWriterBuilder; import com.amazon.ion.impl.bin._Private_IonManagedWriter; @@ -43,7 +40,6 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; diff --git a/test/com/amazon/ion/impl/IonWriterTestCase.java b/test/com/amazon/ion/impl/IonWriterTestCase.java index fdfd52d15b..522b5e59c3 100644 --- a/test/com/amazon/ion/impl/IonWriterTestCase.java +++ b/test/com/amazon/ion/impl/IonWriterTestCase.java @@ -48,10 +48,8 @@ import com.amazon.ion.SystemSymbols; import com.amazon.ion.TestUtils; import com.amazon.ion.UnknownSymbolException; -import com.amazon.ion.impl.bin._Private_IonManagedWriter; import com.amazon.ion.junit.IonAssert; -import com.amazon.ion.system.IonSystemBuilder; -import java.io.ByteArrayInputStream; + import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/test/com/amazon/ion/impl/_Private_ScalarConversionsTest.java b/test/com/amazon/ion/impl/_Private_ScalarConversionsTest.java index c607cbb891..93b9ab350c 100644 --- a/test/com/amazon/ion/impl/_Private_ScalarConversionsTest.java +++ b/test/com/amazon/ion/impl/_Private_ScalarConversionsTest.java @@ -17,10 +17,8 @@ import static org.junit.Assert.*; -import org.junit.Assert; import org.junit.Test; import com.amazon.ion.Decimal; -import static org.junit.Assert.*; public class _Private_ScalarConversionsTest { private long decimalToLong(final Decimal d) { diff --git a/test/com/amazon/ion/impl/lite/IonListSexpLiteSublistTest.java b/test/com/amazon/ion/impl/lite/IonListSexpLiteSublistTest.java index bd607af587..d6fd716404 100644 --- a/test/com/amazon/ion/impl/lite/IonListSexpLiteSublistTest.java +++ b/test/com/amazon/ion/impl/lite/IonListSexpLiteSublistTest.java @@ -19,13 +19,12 @@ import java.util.List; import java.util.ListIterator; -import org.junit.Assert; + import org.junit.Test; import org.junit.runner.RunWith; import com.amazon.ion.IonInt; import com.amazon.ion.IonSequence; import com.amazon.ion.IonValue; -import com.amazon.ion.impl.lite.BaseIonSequenceLiteSublistTestCase; import com.amazon.ion.junit.Injected; import com.amazon.ion.junit.Injected.Inject; diff --git a/test/com/amazon/ion/junit/IonAssert.java b/test/com/amazon/ion/junit/IonAssert.java index ca824ff8fa..a91f1f3d02 100644 --- a/test/com/amazon/ion/junit/IonAssert.java +++ b/test/com/amazon/ion/junit/IonAssert.java @@ -35,7 +35,6 @@ import java.util.Map.Entry; import static com.amazon.ion.SymbolTable.UNKNOWN_SYMBOL_ID; -import static com.amazon.ion.impl._Private_IonConstants.UNKNOWN_SYMBOL_TEXT_PREFIX; import static com.amazon.ion.util.IonTextUtils.printSymbol; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; diff --git a/test/com/amazon/ion/streaming/BadIonStreamingTest.java b/test/com/amazon/ion/streaming/BadIonStreamingTest.java index b847fd79e0..7e48f05de0 100644 --- a/test/com/amazon/ion/streaming/BadIonStreamingTest.java +++ b/test/com/amazon/ion/streaming/BadIonStreamingTest.java @@ -26,8 +26,7 @@ import com.amazon.ion.impl._Private_Utils; import com.amazon.ion.junit.Injected.Inject; import java.io.File; -import java.io.IOException; -import org.junit.Ignore; + import org.junit.Test; public class BadIonStreamingTest diff --git a/test/com/amazon/ion/streaming/ReaderTest.java b/test/com/amazon/ion/streaming/ReaderTest.java index 26608e6272..65eebcf87b 100644 --- a/test/com/amazon/ion/streaming/ReaderTest.java +++ b/test/com/amazon/ion/streaming/ReaderTest.java @@ -32,7 +32,6 @@ import java.math.BigInteger; import java.util.Arrays; -import org.junit.Assert; import org.junit.Ignore; import org.junit.Test;