├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── ci-workflow.yml │ └── pr-workflow.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── benchmarks ├── README.md ├── charts │ ├── array.r │ ├── common.r │ ├── fieldSerializer.r │ ├── string.r │ └── variableEncoding.r ├── lib │ ├── byte-buddy-1.12.7.jar │ ├── commons-cli-1.3.1.jar │ ├── commons-math3-3.2.jar │ ├── jmh-core-1.21.jar │ ├── jmh-generator-annprocess-1.21.jar │ └── jopt-simple-4.6.jar ├── pom.xml ├── run.sh └── src │ └── main │ └── java │ └── com │ └── esotericsoftware │ └── kryo │ └── benchmarks │ ├── BigDecimalBenchmark.java │ ├── ConcurrencyBenchmark.java │ ├── FieldSerializerBenchmark.java │ ├── KryoBenchmarks.java │ ├── MapBenchmark.java │ ├── data │ ├── Image.java │ ├── Media.java │ ├── MediaContent.java │ └── Sample.java │ └── io │ ├── ArrayBenchmark.java │ ├── InputOutputState.java │ ├── StringBenchmark.java │ └── VariableEncodingBenchmark.java ├── build ├── assembly-all.xml ├── commons-lang-2.6.jar ├── junit-platform-console-standalone-1.8.2.jar └── settings-sonatype.xml ├── compat_reports ├── kryo-2.22.jar ├── kryo-2.23.0.jar ├── kryo │ ├── 2.22_to_2.23.0 │ │ └── compat_report.html │ ├── 2.23.0_to_2.24.0 │ │ └── compat_report.html │ ├── 2.24.0_to_3.0.0 │ │ └── compat_report.html │ ├── 3.0.0_to_3.0.1 │ │ └── compat_report.html │ ├── 3.0.1_to_3.0.2 │ │ └── compat_report.html │ ├── 3.0.2_to_3.0.3 │ │ └── compat_report.html │ ├── 3.0.3_to_4.0.0 │ │ └── compat_report.html │ ├── 4.0.0_to_4.0.1 │ │ └── compat_report.html │ ├── 4.0.1_to_4.0.2 │ │ └── compat_report.html │ ├── 4.0.2_to_4.0.3 │ │ └── compat_report.html │ ├── 4.0.2_to_5.0.0-RC1 │ │ └── compat_report.html │ ├── 5.0.0-RC1_to_5.0.0-RC2 │ │ └── compat_report.html │ ├── 5.0.0-RC2_to_5.0.0-RC3 │ │ └── compat_report.html │ ├── 5.0.0-RC4_to_5.0.0-RC5 │ │ └── compat_report.html │ ├── 5.0.0-RC5_to_5.0.0-RC6 │ │ └── compat_report.html │ ├── 5.0.0-RC6_to_5.0.0-RC7 │ │ └── compat_report.html │ ├── 5.0.0-RC7_to_5.0.0-RC8 │ │ └── compat_report.html │ ├── 5.0.0-RC8_to_5.0.0-RC9 │ │ └── compat_report.html │ ├── 5.0.0-RC9_to_5.0.0 │ │ └── compat_report.html │ ├── 5.0.0_to_5.0.1 │ │ └── compat_report.html │ ├── 5.0.1_to_5.0.2 │ │ └── compat_report.html │ ├── 5.0.2_to_5.0.3 │ │ └── compat_report.html │ ├── 5.0.3_to_5.0.4 │ │ └── compat_report.html │ ├── 5.0.4_to_5.1.0 │ │ └── compat_report.html │ ├── 5.1.0_to_5.1.1 │ │ └── compat_report.html │ ├── 5.1.1_to_5.2.0 │ │ └── compat_report.html │ ├── 5.2.0_to_5.2.1 │ │ └── compat_report.html │ ├── 5.2.1_to_5.3.0 │ │ └── compat_report.html │ ├── 5.3.0_to_5.4.0 │ │ └── compat_report.html │ ├── 5.4.0_to_5.5.0 │ │ └── compat_report.html │ ├── 5.5.0_to_5.6.0 │ │ └── compat_report.html │ ├── 5.6.0_to_5.6.1 │ │ └── compat_report.html │ └── 5.6.1_to_5.6.2 │ │ └── compat_report.html └── skip-classes.txt ├── eclipse ├── .classpath ├── .factorypath ├── .importorder ├── .project ├── .settings │ ├── org.eclipse.jdt.apt.core.prefs │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.jdt.ui.prefs └── code-format.xml ├── lib ├── minlog-1.3.1.jar ├── objenesis-3.2.jar └── reflectasm-1.11.9.jar ├── main-versioned └── pom.xml ├── main └── pom.xml ├── pom.xml ├── src └── com │ └── esotericsoftware │ └── kryo │ ├── ClassResolver.java │ ├── DefaultSerializer.java │ ├── Kryo.java │ ├── KryoCopyable.java │ ├── KryoException.java │ ├── KryoSerializable.java │ ├── ReferenceResolver.java │ ├── Registration.java │ ├── Serializer.java │ ├── SerializerFactory.java │ ├── io │ ├── ByteBufferInput.java │ ├── ByteBufferInputStream.java │ ├── ByteBufferOutput.java │ ├── ByteBufferOutputStream.java │ ├── Input.java │ ├── InputChunked.java │ ├── KryoBufferOverflowException.java │ ├── KryoBufferUnderflowException.java │ ├── KryoDataInput.java │ ├── KryoDataOutput.java │ ├── KryoObjectInput.java │ ├── KryoObjectOutput.java │ ├── Output.java │ └── OutputChunked.java │ ├── serializers │ ├── AsmField.java │ ├── BeanSerializer.java │ ├── BlowfishSerializer.java │ ├── CachedFields.java │ ├── ClosureSerializer.java │ ├── CollectionSerializer.java │ ├── CompatibleFieldSerializer.java │ ├── DefaultArraySerializers.java │ ├── DefaultSerializers.java │ ├── DeflateSerializer.java │ ├── EnumMapSerializer.java │ ├── EnumNameSerializer.java │ ├── ExternalizableSerializer.java │ ├── FieldSerializer.java │ ├── ImmutableCollectionsSerializers.java │ ├── ImmutableSerializer.java │ ├── JavaSerializer.java │ ├── MapSerializer.java │ ├── OptionalSerializers.java │ ├── RecordSerializer.java │ ├── ReflectField.java │ ├── TaggedFieldSerializer.java │ ├── TimeSerializers.java │ ├── UnsafeField.java │ └── VersionFieldSerializer.java │ ├── unsafe │ ├── UnsafeByteBufferInput.java │ ├── UnsafeByteBufferOutput.java │ ├── UnsafeInput.java │ ├── UnsafeOutput.java │ └── UnsafeUtil.java │ └── util │ ├── CuckooObjectMap.java │ ├── DefaultClassResolver.java │ ├── DefaultGenerics.java │ ├── DefaultInstantiatorStrategy.java │ ├── Generics.java │ ├── GenericsUtil.java │ ├── HashMapReferenceResolver.java │ ├── IdentityMap.java │ ├── IdentityObjectIntMap.java │ ├── IntArray.java │ ├── IntMap.java │ ├── ListReferenceResolver.java │ ├── MapReferenceResolver.java │ ├── NoGenerics.java │ ├── Null.java │ ├── ObjectIntMap.java │ ├── ObjectMap.java │ ├── Pool.java │ └── Util.java ├── test-jdk11 └── com │ └── esotericsoftware │ └── kryo │ ├── TestDataJava11.java │ └── serializers │ └── ImmutableCollectionsSerializersTest.java ├── test-jdk17 └── com │ └── esotericsoftware │ └── kryo │ ├── TestDataJava17.java │ └── serializers │ └── RecordSerializerTest.java ├── test-kotlin └── com.esotericsoftware.kryo │ └── SerializationTest.kt └── test ├── com └── esotericsoftware │ └── kryo │ ├── CopyTest.java │ ├── DefaultInstantiatorStrategyTest.java │ ├── DepthTest.java │ ├── GarbageCollectionTest.java │ ├── KryoAssert.java │ ├── KryoTestCase.java │ ├── ReferenceTest.java │ ├── ReflectionAssert.java │ ├── RegistrationTest.java │ ├── SerializationBenchmarkTest.java │ ├── SerializationCompatTest.java │ ├── SerializationCompatTestData.java │ ├── Unsafe.java │ ├── WarnUnregisteredClassesTest.java │ ├── io │ ├── ByteBufferInputOutputTest.java │ ├── ChunkedTest.java │ ├── InputOutputTest.java │ ├── UnsafeByteBufferInputOutputTest.java │ └── UnsafeInputOutputTest.java │ ├── serializers │ ├── ArraySerializerTest.java │ ├── BeanSerializerTest.java │ ├── BlowfishSerializerTest.java │ ├── ClosureSerializerTest.java │ ├── CollectionSerializerTest.java │ ├── CompatibleFieldSerializerTest.java │ ├── DefaultSerializersTest.java │ ├── DeflateSerializerTest.java │ ├── EnumNameSerializerTest.java │ ├── ExternalizableSerializerTest.java │ ├── FieldSerializerGenericsTest.java │ ├── FieldSerializerInheritanceTest.java │ ├── FieldSerializerTest.java │ ├── GenericsTest.java │ ├── JavaSerializerTest.java │ ├── MapSerializerTest.java │ ├── OptionalSerializersTest.java │ ├── ParallelSerializationTest.java │ ├── SerializerPriorityTest.java │ ├── TaggedFieldSerializerTest.java │ ├── TimeSerializersTest.java │ └── VersionedFieldSerializerTest.java │ └── util │ ├── GenericsUtilTest.java │ ├── PoolTest.java │ └── UtilTest.java └── resources ├── TestData-bytebuffer.ser ├── TestData-standard.ser ├── TestDataJava11-bytebuffer.ser ├── TestDataJava11-standard.ser ├── TestDataJava17-bytebuffer.ser ├── TestDataJava17-standard.ser ├── TestDataJava8-bytebuffer.ser └── TestDataJava8-standard.ser /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug, needs repro 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Provide a minimal reproducible example of the problem, ideally in the form of a runnable test-case. 15 | 16 | **Environment:** 17 | - OS: [e.g. Ubuntu] 18 | - JDK Version: [e.g. 11] 19 | - Kryo Version: [e.g. 5.1.0] 20 | 21 | **Additional context** 22 | Add any other context about the problem here. 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/ci-workflow.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | env: 13 | PUBLISH_ARTIFACTS: true 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-java@v4 18 | with: 19 | distribution: 'temurin' 20 | java-version: 11 21 | cache: 'maven' 22 | 23 | - name: Build with JDK 11 24 | run: mvn -B install --no-transfer-progress -DskipTests 25 | 26 | - uses: actions/setup-java@v4 27 | with: 28 | distribution: 'temurin' 29 | java-version: 8 30 | - name: Test with JDK 8 31 | run: mvn -v && mvn -B test 32 | 33 | - uses: actions/setup-java@v4 34 | with: 35 | distribution: 'temurin' 36 | java-version: 11 37 | - name: Test with JDK 11 38 | run: mvn -v && mvn -B test 39 | 40 | - uses: actions/setup-java@v4 41 | with: 42 | distribution: 'temurin' 43 | java-version: 17 44 | - name: Test with JDK 17 45 | run: mvn -v && mvn -B test 46 | 47 | - uses: actions/setup-java@v4 48 | with: 49 | distribution: 'temurin' 50 | java-version: 21 51 | - name: Test with JDK 21 52 | run: mvn -v && mvn -B test 53 | 54 | - uses: actions/setup-java@v4 55 | with: 56 | distribution: 'temurin' 57 | java-version: 24 58 | - name: Test with JDK 24 59 | run: mvn -v && mvn -B test 60 | 61 | - name: Set up settings.xml for Sonatype 62 | uses: actions/setup-java@v4 63 | with: 64 | distribution: 'temurin' 65 | java-version: 11 66 | 67 | - name: Publish SNAPSHOT version to Sonatype (we can skip tests, since we only deploy, if the build workflow succeeded) 68 | run: mvn -v && mvn -B -P requireSnapshot --no-transfer-progress -DskipTests deploy --settings build/settings-sonatype.xml 69 | if: env.PUBLISH_ARTIFACTS == 'true' 70 | env: 71 | SONATYPE_USERNAME: yJQKaLoU 72 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PW_TOKEN }} 73 | -------------------------------------------------------------------------------- /.github/workflows/pr-workflow.yml: -------------------------------------------------------------------------------- 1 | name: PR Build 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-java@v4 12 | with: 13 | distribution: 'temurin' 14 | java-version: 11 15 | cache: 'maven' 16 | 17 | - name: Build with JDK 11 18 | run: mvn -B install --no-transfer-progress -DskipTests 19 | 20 | - uses: actions/setup-java@v4 21 | with: 22 | distribution: 'temurin' 23 | java-version: 8 24 | - name: Test with JDK 8 25 | run: mvn -v && mvn -B test 26 | 27 | - uses: actions/setup-java@v4 28 | with: 29 | distribution: 'temurin' 30 | java-version: 11 31 | - name: Test with JDK 11 32 | run: mvn -v && mvn -B test 33 | 34 | - uses: actions/setup-java@v4 35 | with: 36 | distribution: 'temurin' 37 | java-version: 17 38 | - name: Test with JDK 17 39 | run: mvn -v && mvn -B test 40 | 41 | - uses: actions/setup-java@v4 42 | with: 43 | distribution: 'temurin' 44 | java-version: 21 45 | - name: Test with JDK 21 46 | run: mvn -v && mvn -B test 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Temporary Files 2 | *~ 3 | .*.swp 4 | .DS_STORE 5 | *.iml 6 | 7 | benchmarks/charts/results 8 | jmh-result.csv 9 | .R* 10 | 11 | bin/ 12 | target/ 13 | 14 | # Mac specific files 15 | .DS_Store 16 | 17 | # Vim 18 | .*.sw[0-9a-zA-Z] 19 | 20 | # IntelliJ 21 | .idea/ 22 | *.iml 23 | *.ipr 24 | *.iws 25 | 26 | # Eclipse 27 | .apt_generated/ 28 | .Rproj.user 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Project license(s): 3-Clause BSD License 2 | 3 | * You will only Submit Contributions where You have authored 100% of the content. 4 | 5 | * You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the Contributions. 6 | 7 | * Whatever content You Contribute will be under the copyright and license listed in LICENSE.md. 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2025, Nathan Sweet 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /benchmarks/README.md: -------------------------------------------------------------------------------- 1 | # Kryo Benchmarks 2 | 3 | This subproject contains [JMH](http://openjdk.java.net/projects/code-tools/jmh/) benchmarks for Kryo. The [R/ggplot2 files](https://github.com/EsotericSoftware/kryo/tree/master/benchmarks/charts) are used to generate charts from the benchmark results. 4 | 5 | ## Usage 6 | 7 | ### With Maven 8 | 9 | To run benchmarks execute: 10 | ``` 11 | mvn -f benchmarks/pom.xml compile exec:java -Dexec.args="[parameters]" 12 | ``` 13 | 14 | Where `[parameters]` should be replaced with JMH parameters. 15 | 16 | ### Without Maven 17 | 18 | This assumes your IDE has compiled Kryo to the `bin` directory, including the benchmarks source and processing of the JMH annotations. 19 | ``` 20 | java -cp "bin;lib/*;benchmarks/lib/*" com.esotericsoftware.kryo.benchmarks.KryoBenchmarks [parameters] 21 | ``` 22 | Where `[parameters]` should be replaced with JMH parameters. 23 | 24 | ### Parameters 25 | 26 | If no JMH parameters are given, the benchmarks are run with settings only suitable for development (fork 0, short runs). A full list of JMH parameters can be found by running: 27 | ``` 28 | java -cp "benchmarks/lib/*" org.openjdk.jmh.Main -h 29 | ``` 30 | Or by digging through the [JMH source](http://hg.openjdk.java.net/code-tools/jmh/file/3769055ad883/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java). 31 | 32 | Running without parameters is equivalent to: 33 | ``` 34 | -f 0 -wi 1 -i 1 -t 1 -w 1s -r 1s 35 | ``` 36 | 37 | The standard parameters to obtain reasonable results are: 38 | ``` 39 | -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s 40 | ``` 41 | 42 | To run only specific benchmarks, specify the benchmark class name(s): 43 | ``` 44 | -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s FieldSerializerBenchmark 45 | ``` 46 | 47 | To run only a subset of a benchmark, specify the benchmark class name and the methods: 48 | ``` 49 | -f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s FieldSerializerBenchmark.field FieldSerializerBenchmark.tagged 50 | ``` 51 | -------------------------------------------------------------------------------- /benchmarks/charts/array.r: -------------------------------------------------------------------------------- 1 | 2 | source("../common.r") 3 | 4 | data = jmhCSV("array.csv") 5 | 6 | data = data[,grep("^(Benchmark|Score|Error|bufferType)$", colnames(data))] # keep only these columns 7 | 8 | g = jmhBarChart(data, "bufferType", "Buffer type", "Operation", "Seconds per 12M operations", "ArrayBenchmark") 9 | 10 | if (!rstudio) png("array.png", 1024, 445) 11 | grid.arrange(g) 12 | -------------------------------------------------------------------------------- /benchmarks/charts/common.r: -------------------------------------------------------------------------------- 1 | 2 | options(scipen=999) 3 | 4 | rstudio = Sys.getenv("RSTUDIO_USER_IDENTITY") != "" 5 | 6 | loadLibrary = function (name) { 7 | if (!require(name, character.only=TRUE)) { 8 | install.packages(name) 9 | library(name, character.only=TRUE) 10 | } 11 | } 12 | loadLibrary("ggplot2") 13 | loadLibrary("gridExtra") 14 | 15 | jmhCSV = function (path) { 16 | data = read.csv(path, sep=",", header=T) 17 | 18 | # delete all before last dot in benchmark names 19 | data$Benchmark = sub("^.+\\.", "", data$Benchmark) 20 | 21 | # rename Error column 22 | colnames(data)[colnames(data) == "Score.Error..99.9.."] = "Error" 23 | 24 | # remove Param prefix 25 | colnames(data) = sub("Param..", "", colnames(data)) 26 | 27 | data 28 | } 29 | 30 | jmhBarChart = function (data, fill, fillLabel, xLabel, yLabel, title=NULL) { 31 | g = ggplot(data, aes(x=Benchmark, y=Score, fill=data[,fill], ymin=Score - Error, ymax=Score + Error)) 32 | g = g + geom_bar(stat="identity", position="dodge", color="black", width=0.9) 33 | g = g + geom_errorbar(width=.33, size=.5, position=position_dodge(0.9)) 34 | g = g + labs(x=xLabel, y=yLabel, fill=fillLabel) + geom_hline(yintercept=0) 35 | if (!rstudio) { 36 | if (length(title) != 0) g = g + ggtitle(title) 37 | g = g + theme(text=element_text(size=16)) 38 | } 39 | g 40 | } 41 | -------------------------------------------------------------------------------- /benchmarks/charts/fieldSerializer.r: -------------------------------------------------------------------------------- 1 | 2 | source("../common.r") 3 | loadLibrary("gridExtra") 4 | 5 | data = jmhCSV("fieldSerializer.csv") 6 | 7 | data$references = sub("true", "refs", data$references) 8 | data$references = sub("false", "no refs", data$references) 9 | 10 | data$chunked = sub("true", ", chunked", data$chunked) 11 | data$chunked = sub("false", "", data$chunked) 12 | 13 | data$Type = paste(data$references, data$chunked, sep="") 14 | 15 | data = data[,grep("^(Benchmark|Type|Score|Error|objectType)$", colnames(data))] # keep only these columns 16 | 17 | g1 = jmhBarChart(subset(data, objectType == "sample"), "Type", "Serializer settings", "Sample", "Round trips per second") 18 | g2 = jmhBarChart(subset(data, objectType == "media"), "Type", "Serializer settings", "Media", "Round trips per second") 19 | 20 | if (!rstudio) { 21 | g1 = g1 + ggtitle("FieldSerializerBenchmark") 22 | png("fieldSerializer.png", 1024, 890) 23 | } 24 | grid.arrange(g1, g2) 25 | -------------------------------------------------------------------------------- /benchmarks/charts/string.r: -------------------------------------------------------------------------------- 1 | 2 | source("../common.r") 3 | 4 | data = jmhCSV("string.csv") 5 | 6 | data = data[,grep("^(Benchmark|Score|Error|bufferType)$", colnames(data))] # keep only these columns 7 | 8 | g = jmhBarChart(data, "bufferType", "Buffer type", "Operation", "Seconds per 12M operations", "StringBenchmark") 9 | 10 | if (!rstudio) png("string.png", 1024, 445) 11 | grid.arrange(g) 12 | -------------------------------------------------------------------------------- /benchmarks/charts/variableEncoding.r: -------------------------------------------------------------------------------- 1 | 2 | source("../common.r") 3 | 4 | data = jmhCSV("variableEncoding.csv") 5 | 6 | data = data[,grep("^(Benchmark|Score|Error|bufferType)$", colnames(data))] # keep only these columns 7 | 8 | g = jmhBarChart(data, "bufferType", "Buffer type", "Operation", "Seconds per 150M operations", "VariableEncodingBenchmark") 9 | 10 | if (!rstudio) png("variableEncoding.png", 1024, 445) 11 | grid.arrange(g) 12 | -------------------------------------------------------------------------------- /benchmarks/lib/byte-buddy-1.12.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/byte-buddy-1.12.7.jar -------------------------------------------------------------------------------- /benchmarks/lib/commons-cli-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/commons-cli-1.3.1.jar -------------------------------------------------------------------------------- /benchmarks/lib/commons-math3-3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/commons-math3-3.2.jar -------------------------------------------------------------------------------- /benchmarks/lib/jmh-core-1.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/jmh-core-1.21.jar -------------------------------------------------------------------------------- /benchmarks/lib/jmh-generator-annprocess-1.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/jmh-generator-annprocess-1.21.jar -------------------------------------------------------------------------------- /benchmarks/lib/jopt-simple-4.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/benchmarks/lib/jopt-simple-4.6.jar -------------------------------------------------------------------------------- /benchmarks/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.esotericsoftware 6 | kryo-parent 7 | 5.6.3-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | kryo-benchmarks 12 | jar 13 | 14 | Kryo Benchmarks 15 | JMH benchmarks for Kryo. 16 | 17 | 18 | ${basedir}/.. 19 | 1.37 20 | 1.17.5 21 | benchmarks 22 | UTF-8 23 | 24 | 25 | 26 | 27 | com.esotericsoftware 28 | kryo 29 | ${project.version} 30 | 31 | 32 | org.openjdk.jmh 33 | jmh-core 34 | ${jmh.version} 35 | 36 | 37 | org.openjdk.jmh 38 | jmh-generator-annprocess 39 | ${jmh.version} 40 | provided 41 | 42 | 43 | net.bytebuddy 44 | byte-buddy 45 | ${byte-buddy.version} 46 | 47 | 48 | 49 | 50 | src/main/java 51 | 52 | 53 | maven-dependency-plugin 54 | 3.8.1 55 | 56 | 57 | build-classpath 58 | 59 | build-classpath 60 | 61 | 62 | runtime 63 | depClasspath 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.codehaus.mojo 71 | exec-maven-plugin 72 | 3.5.0 73 | 74 | 75 | run-tests 76 | 77 | java 78 | 79 | 80 | 81 | 82 | com.esotericsoftware.kryo.benchmarks.KryoBenchmarks 83 | 84 | 85 | java.class.path 86 | ${project.build.outputDirectory}${path.separator}${depClasspath} 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /benchmarks/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | args="-f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s -rf csv -rff" 4 | jmh="$JAVA_HOME/bin/java -cp ../eclipse/bin;../eclipse/.apt_generated;../lib/*;lib/* com.esotericsoftware.kryo.benchmarks.KryoBenchmarks $args" 5 | 6 | set -ex 7 | 8 | mkdir -p charts/results 9 | $jmh charts/results/fieldSerializer.csv FieldSerializerBenchmark 10 | $jmh charts/results/array.csv ArrayBenchmark 11 | $jmh charts/results/string.csv StringBenchmark 12 | $jmh charts/results/variableEncoding.csv VariableEncodingBenchmark 13 | 14 | cd charts/results 15 | find ../*.r -type f -exec echo "{}:" \; -exec Rscript {} \; 16 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/BigDecimalBenchmark.java: -------------------------------------------------------------------------------- 1 | package com.esotericsoftware.kryo.benchmarks; 2 | 3 | import com.esotericsoftware.kryo.Serializer; 4 | import com.esotericsoftware.kryo.io.Input; 5 | import com.esotericsoftware.kryo.io.Output; 6 | import com.esotericsoftware.kryo.serializers.DefaultSerializers; 7 | import org.openjdk.jmh.annotations.Benchmark; 8 | import org.openjdk.jmh.annotations.Level; 9 | import org.openjdk.jmh.annotations.Param; 10 | import org.openjdk.jmh.annotations.Scope; 11 | import org.openjdk.jmh.annotations.Setup; 12 | import org.openjdk.jmh.annotations.State; 13 | import org.openjdk.jmh.annotations.TearDown; 14 | import org.openjdk.jmh.runner.Runner; 15 | import org.openjdk.jmh.runner.RunnerException; 16 | import org.openjdk.jmh.runner.options.Options; 17 | import org.openjdk.jmh.runner.options.OptionsBuilder; 18 | 19 | import java.math.BigDecimal; 20 | 21 | import static java.lang.Integer.parseInt; 22 | import static java.math.BigDecimal.ONE; 23 | import static java.math.BigDecimal.ZERO; 24 | import static java.util.concurrent.TimeUnit.MICROSECONDS; 25 | import static org.openjdk.jmh.runner.options.TimeValue.seconds; 26 | 27 | public class BigDecimalBenchmark { 28 | 29 | @State(Scope.Thread) 30 | public static class MyState { 31 | final Serializer serializer = new DefaultSerializers.BigDecimalSerializer(); 32 | 33 | Output output; 34 | Input input; 35 | 36 | @Param({ 37 | "null", "zero", "one", "0", 38 | "2", "10", "max_in_long", "20", // twenty is more than the number of digits in Long.MAX_VALUE 39 | "-2", "-10", "min_in_long", "-20" // twenty is more than the number of digits in Long.MIN_VALUE 40 | }) 41 | String numOfDigits = "5"; 42 | int scale = 2; 43 | 44 | BigDecimal decimal; 45 | 46 | @Setup(Level.Iteration) 47 | public void setUp() { 48 | decimal = newDecimal(numOfDigits, scale); 49 | output = new Output(2, -1); 50 | serializer.write(null, output, decimal); 51 | input = new Input(output.toBytes()); 52 | output.reset(); 53 | } 54 | 55 | private static BigDecimal newDecimal(String numOfDigits, int scale) { 56 | switch (numOfDigits) { 57 | case "null": return null; 58 | case "zero": return ZERO; 59 | case "one": return ONE; 60 | case "0": return BigDecimal.valueOf(0, scale); 61 | case "max_in_long": return BigDecimal.valueOf(Long.MAX_VALUE, scale); 62 | case "min_in_long": return BigDecimal.valueOf(Long.MIN_VALUE, scale); 63 | default: 64 | int digits = parseInt(numOfDigits.replace("-", "")); 65 | BigDecimal d = BigDecimal.valueOf(10, 1 - digits).subtract(ONE).scaleByPowerOfTen(-scale); // '9' repeated numOfDigit times 66 | return numOfDigits.charAt(0) != '-' ? d : d.negate(); 67 | } 68 | } 69 | 70 | @TearDown(Level.Iteration) 71 | public void tearDown () { 72 | output.close(); 73 | input.close(); 74 | } 75 | } 76 | 77 | @Benchmark 78 | public byte[] write (MyState state) { 79 | state.output.reset(); 80 | state.serializer.write(null, state.output, state.decimal); 81 | return state.output.getBuffer(); 82 | } 83 | 84 | @Benchmark 85 | public BigDecimal read (MyState state) { 86 | state.input.reset(); 87 | return state.serializer.read(null, state.input, BigDecimal.class); 88 | } 89 | 90 | public static void main (String[] args) throws RunnerException { 91 | final Options opt = new OptionsBuilder() 92 | .include(".*" + BigDecimalBenchmark.class.getSimpleName() + ".*") 93 | .timeUnit(MICROSECONDS) 94 | .warmupIterations(1) 95 | .warmupTime(seconds(1)) 96 | .measurementIterations(4) 97 | .measurementTime(seconds(1)) 98 | .forks(1) 99 | .build(); 100 | new Runner(opt).run(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/KryoBenchmarks.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks; 21 | 22 | import org.openjdk.jmh.Main; 23 | 24 | public class KryoBenchmarks { 25 | /** To run from command line: $ mvn clean install exec:java -Dexec.args="-f 4 -wi 5 -i 3 -t 2 -w 2s -r 2s" 26 | *

27 | * Fork 0 can be used for debugging/development, eg: -f 0 -wi 1 -i 1 -t 1 -w 1s -r 1s [benchmarkClassName] */ 28 | static public void main (String[] args) throws Exception { 29 | if (args.length == 0) { 30 | String commandLine = "-f 0 -wi 1 -i 1 -t 1 -w 1s -r 1s " // For developement only (fork 0, short runs). 31 | // + "-bs 2500000 ArrayBenchmark" // 32 | // + "-rf csv FieldSerializerBenchmark.field FieldSerializerBenchmark.tagged" // 33 | // + "FieldSerializerBenchmark.tagged" // 34 | ; 35 | System.out.println(commandLine); 36 | args = commandLine.split(" "); 37 | } 38 | Main.main(args); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/Image.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.data; 21 | 22 | import com.esotericsoftware.kryo.serializers.TaggedFieldSerializer.Tag; 23 | 24 | public class Image { 25 | @Tag(0) public String uri; 26 | @Tag(1) public String title; // Can be null. 27 | @Tag(2) public int width; 28 | @Tag(3) public int height; 29 | @Tag(4) public Size size; 30 | @Tag(5) public Media media; // Can be null. 31 | 32 | public Image () { 33 | } 34 | 35 | public Image (String uri, String title, int width, int height, Size size, Media media) { 36 | this.height = height; 37 | this.title = title; 38 | this.uri = uri; 39 | this.width = width; 40 | this.size = size; 41 | this.media = media; 42 | } 43 | 44 | public boolean equals (Object o) { 45 | if (this == o) return true; 46 | if (o == null || getClass() != o.getClass()) return false; 47 | Image other = (Image)o; 48 | if (height != other.height) return false; 49 | if (width != other.width) return false; 50 | if (size != other.size) return false; 51 | if (title != null ? !title.equals(other.title) : other.title != null) return false; 52 | if (uri != null ? !uri.equals(other.uri) : other.uri != null) return false; 53 | return true; 54 | } 55 | 56 | public int hashCode () { 57 | int result = uri != null ? uri.hashCode() : 0; 58 | result = 31 * result + (title != null ? title.hashCode() : 0); 59 | result = 31 * result + width; 60 | result = 31 * result + height; 61 | result = 31 * result + (size != null ? size.hashCode() : 0); 62 | return result; 63 | } 64 | 65 | public String toString () { 66 | StringBuilder sb = new StringBuilder(); 67 | sb.append("[Image "); 68 | sb.append("uri=").append(uri); 69 | sb.append(", title=").append(title); 70 | sb.append(", width=").append(width); 71 | sb.append(", height=").append(height); 72 | sb.append(", size=").append(size); 73 | sb.append("]"); 74 | return sb.toString(); 75 | } 76 | 77 | static public enum Size { 78 | SMALL, LARGE 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/MediaContent.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.data; 21 | 22 | import com.esotericsoftware.kryo.benchmarks.data.Image.Size; 23 | import com.esotericsoftware.kryo.benchmarks.data.Media.Player; 24 | import com.esotericsoftware.kryo.serializers.TaggedFieldSerializer.Tag; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | public class MediaContent implements java.io.Serializable { 30 | @Tag(0) public Media media; 31 | @Tag(1) public List images; 32 | 33 | public MediaContent () { 34 | } 35 | 36 | public MediaContent (Media media, List images) { 37 | this.media = media; 38 | this.images = images; 39 | } 40 | 41 | public MediaContent populate (boolean circularReference) { 42 | media = new Media(); 43 | media.uri = "http://javaone.com/keynote.ogg"; 44 | media.width = 641; 45 | media.height = 481; 46 | media.format = "video/theora\u1234"; 47 | media.duration = 18000001; 48 | media.size = 58982401; 49 | media.persons = new ArrayList(); 50 | media.persons.add("Bill Gates, Jr."); 51 | media.persons.add("Steven Jobs"); 52 | media.player = Player.FLASH; 53 | media.copyright = "Copyright (c) 2009, Scooby Dooby Doo"; 54 | images = new ArrayList(); 55 | Media media = circularReference ? this.media : null; 56 | images.add(new Image("http://javaone.com/keynote_huge.jpg", "Javaone Keynote\u1234", 32000, 24000, Size.LARGE, media)); 57 | images.add(new Image("http://javaone.com/keynote_large.jpg", null, 1024, 768, Size.LARGE, media)); 58 | images.add(new Image("http://javaone.com/keynote_small.jpg", null, 320, 240, Size.SMALL, media)); 59 | return this; 60 | } 61 | 62 | public boolean equals (Object o) { 63 | if (this == o) return true; 64 | if (o == null || getClass() != o.getClass()) return false; 65 | MediaContent other = (MediaContent)o; 66 | if (images != null ? !images.equals(other.images) : other.images != null) return false; 67 | if (media != null ? !media.equals(other.media) : other.media != null) return false; 68 | return true; 69 | } 70 | 71 | public int hashCode () { 72 | int result = media != null ? media.hashCode() : 0; 73 | result = 31 * result + (images != null ? images.hashCode() : 0); 74 | return result; 75 | } 76 | 77 | public String toString () { 78 | StringBuilder sb = new StringBuilder(); 79 | sb.append("[MediaContent: "); 80 | sb.append("media=").append(media); 81 | sb.append(", images=").append(images); 82 | sb.append("]"); 83 | return sb.toString(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/io/ArrayBenchmark.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.io; 21 | 22 | import org.openjdk.jmh.annotations.Benchmark; 23 | import org.openjdk.jmh.annotations.BenchmarkMode; 24 | import org.openjdk.jmh.annotations.Measurement; 25 | import org.openjdk.jmh.annotations.Mode; 26 | import org.openjdk.jmh.annotations.Scope; 27 | import org.openjdk.jmh.annotations.State; 28 | 29 | @BenchmarkMode(Mode.SingleShotTime) 30 | @Measurement(batchSize = 12000000) 31 | public class ArrayBenchmark { 32 | @Benchmark 33 | public void writeInts (WriteIntsState state) { 34 | state.reset(); 35 | state.output.writeInts(state.ints, 0, state.ints.length); 36 | } 37 | 38 | @Benchmark 39 | public void readInts (ReadIntsState state) { 40 | state.reset(); 41 | state.input.readInts(state.ints.length); 42 | } 43 | 44 | @Benchmark 45 | public void writeVarInts (WriteIntsState state) { 46 | state.reset(); 47 | state.output.writeInts(state.ints, 0, state.ints.length, true); 48 | } 49 | 50 | @Benchmark 51 | public void readVarInts (ReadIntsState state) { 52 | state.reset(); 53 | state.input.readInts(state.ints.length, true); 54 | } 55 | 56 | @Benchmark 57 | public void writeLongs (WriteLongsState state) { 58 | state.reset(); 59 | state.output.writeLongs(state.longs, 0, state.longs.length); 60 | } 61 | 62 | @Benchmark 63 | public void readLongs (ReadLongsState state) { 64 | state.reset(); 65 | state.input.readLongs(state.longs.length); 66 | } 67 | 68 | @Benchmark 69 | public void writeVarLongs (WriteLongsState state) { 70 | state.reset(); 71 | state.output.writeLongs(state.longs, 0, state.longs.length, true); 72 | } 73 | 74 | @Benchmark 75 | public void readVarLongs (ReadLongsState state) { 76 | state.reset(); 77 | state.input.readLongs(state.longs.length, true); 78 | } 79 | 80 | // 81 | 82 | @State(Scope.Thread) 83 | static public class WriteIntsState extends InputOutputState { 84 | public int[] ints = {0, 1, 2, 3, 4, 5, 63, 64, 65, 127, 128, 129, 4000, 5000, 6000, 16000, 32000, 256000, 1024000, -1, -2, 85 | -3, -4, Integer.MIN_VALUE, Integer.MAX_VALUE}; 86 | } 87 | 88 | @State(Scope.Thread) 89 | static public class ReadIntsState extends WriteIntsState { 90 | public void setup () { 91 | super.setup(); 92 | new ArrayBenchmark().writeInts(this); 93 | } 94 | } 95 | 96 | @State(Scope.Thread) 97 | static public class WriteLongsState extends InputOutputState { 98 | public long[] longs = {0, 1, 2, 3, 4, 5, 63, 64, 65, 127, 128, 129, 4000, 5000, 6000, 16000, 32000, 256000, 1024000, -1, -2, 99 | -3, -4, Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE, 9999999999l}; 100 | 101 | public void setup () { 102 | super.setup(); 103 | new ArrayBenchmark().writeLongs(this); 104 | } 105 | } 106 | 107 | @State(Scope.Thread) 108 | static public class ReadLongsState extends WriteLongsState { 109 | public void setup () { 110 | super.setup(); 111 | new ArrayBenchmark().writeLongs(this); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/io/InputOutputState.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.io; 21 | 22 | import com.esotericsoftware.kryo.io.ByteBufferInput; 23 | import com.esotericsoftware.kryo.io.ByteBufferOutput; 24 | import com.esotericsoftware.kryo.io.Input; 25 | import com.esotericsoftware.kryo.io.Output; 26 | import com.esotericsoftware.kryo.unsafe.UnsafeByteBufferInput; 27 | import com.esotericsoftware.kryo.unsafe.UnsafeByteBufferOutput; 28 | import com.esotericsoftware.kryo.unsafe.UnsafeInput; 29 | import com.esotericsoftware.kryo.unsafe.UnsafeOutput; 30 | 31 | import org.openjdk.jmh.annotations.Level; 32 | import org.openjdk.jmh.annotations.Param; 33 | import org.openjdk.jmh.annotations.Scope; 34 | import org.openjdk.jmh.annotations.Setup; 35 | import org.openjdk.jmh.annotations.State; 36 | 37 | @State(Scope.Thread) 38 | public class InputOutputState { 39 | @Param() public InputOutputState.BufferType bufferType; 40 | 41 | Output output; 42 | Input input; 43 | 44 | @Setup(Level.Trial) 45 | public void setup () { 46 | switch (bufferType) { 47 | case array: 48 | output = new Output(1024 * 512); 49 | input = new Input(output.getBuffer()); 50 | break; 51 | case unsafeArray: 52 | output = new UnsafeOutput(1024 * 512); 53 | input = new UnsafeInput(output.getBuffer()); 54 | break; 55 | case byteBuffer: 56 | output = new ByteBufferOutput(1024 * 512); 57 | input = new ByteBufferInput(((ByteBufferOutput)output).getByteBuffer()); 58 | break; 59 | case unsafeByteBuffer: 60 | output = new UnsafeByteBufferOutput(1024 * 512); 61 | input = new UnsafeByteBufferInput(((UnsafeByteBufferOutput)output).getByteBuffer()); 62 | break; 63 | } 64 | } 65 | 66 | public void reset () { 67 | input.setPosition(0); 68 | output.setPosition(0); 69 | } 70 | 71 | static public enum BufferType { 72 | array, unsafeArray, byteBuffer, unsafeByteBuffer 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/io/StringBenchmark.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.io; 21 | 22 | import org.openjdk.jmh.annotations.Benchmark; 23 | import org.openjdk.jmh.annotations.BenchmarkMode; 24 | import org.openjdk.jmh.annotations.Measurement; 25 | import org.openjdk.jmh.annotations.Mode; 26 | import org.openjdk.jmh.annotations.Scope; 27 | import org.openjdk.jmh.annotations.State; 28 | 29 | @BenchmarkMode(Mode.SingleShotTime) 30 | @Measurement(batchSize = 12000000) 31 | public class StringBenchmark { 32 | @Benchmark 33 | public void writeString (InputOutputState state) { 34 | state.reset(); 35 | state.output.writeString("abc0123456789"); // Short enough to be detected as ASCII. 36 | } 37 | 38 | @Benchmark 39 | public String readString (ReadString state) { 40 | state.reset(); 41 | return state.input.readString(); 42 | } 43 | 44 | @Benchmark 45 | public void writeStringLong (InputOutputState state) { 46 | state.reset(); 47 | state.output.writeString( 48 | "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789"); 49 | } 50 | 51 | @Benchmark 52 | public String readStringLong (ReadStringLong state) { 53 | state.reset(); 54 | return state.input.readString(); 55 | } 56 | 57 | @Benchmark 58 | public void writeAsciiLong (InputOutputState state) { 59 | state.reset(); 60 | state.output.writeAscii( 61 | "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789"); 62 | } 63 | 64 | @Benchmark 65 | public String readAsciiLong (ReadAsciiLong state) { 66 | state.reset(); 67 | return state.input.readString(); 68 | } 69 | 70 | // 71 | 72 | @State(Scope.Thread) 73 | static public class ReadString extends InputOutputState { 74 | public void setup () { 75 | super.setup(); 76 | new StringBenchmark().writeString(this); 77 | } 78 | } 79 | 80 | @State(Scope.Thread) 81 | static public class ReadStringLong extends InputOutputState { 82 | public void setup () { 83 | super.setup(); 84 | new StringBenchmark().writeStringLong(this); 85 | } 86 | } 87 | 88 | @State(Scope.Thread) 89 | static public class ReadAsciiLong extends InputOutputState { 90 | public void setup () { 91 | super.setup(); 92 | new StringBenchmark().writeAsciiLong(this); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/io/VariableEncodingBenchmark.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.benchmarks.io; 21 | 22 | import org.openjdk.jmh.annotations.Benchmark; 23 | import org.openjdk.jmh.annotations.BenchmarkMode; 24 | import org.openjdk.jmh.annotations.Measurement; 25 | import org.openjdk.jmh.annotations.Mode; 26 | import org.openjdk.jmh.annotations.Scope; 27 | import org.openjdk.jmh.annotations.State; 28 | 29 | @BenchmarkMode(Mode.SingleShotTime) 30 | @Measurement(batchSize = 150000000) 31 | public class VariableEncodingBenchmark { 32 | @Benchmark 33 | public void writeInt (InputOutputState state) { 34 | state.reset(); 35 | state.output.writeInt(1234); 36 | } 37 | 38 | @Benchmark 39 | public void readInt (ReadInt state) { 40 | state.reset(); 41 | state.input.readInt(); 42 | } 43 | 44 | @Benchmark 45 | public void writeVarInt (InputOutputState state) { 46 | state.reset(); 47 | state.output.writeVarInt(1234, true); 48 | } 49 | 50 | @Benchmark 51 | public int readVarInt (ReadVarInt state) { 52 | state.reset(); 53 | return state.input.readVarInt(true); 54 | } 55 | 56 | @Benchmark 57 | public void writeLong (InputOutputState state) { 58 | state.reset(); 59 | state.output.writeLong(12341234); 60 | } 61 | 62 | @Benchmark 63 | public long readLong (ReadLong state) { 64 | state.reset(); 65 | return state.input.readLong(); 66 | } 67 | 68 | @Benchmark 69 | public void writeVarLong (InputOutputState state) { 70 | state.reset(); 71 | state.output.writeVarLong(12341234, true); 72 | } 73 | 74 | @Benchmark 75 | public long readVarLong (ReadLong state) { 76 | state.reset(); 77 | return state.input.readVarLong(true); 78 | } 79 | 80 | // 81 | 82 | @State(Scope.Thread) 83 | static public class ReadInt extends InputOutputState { 84 | public ReadInt () { 85 | new VariableEncodingBenchmark().writeInt(this); 86 | } 87 | } 88 | 89 | @State(Scope.Thread) 90 | static public class ReadVarInt extends InputOutputState { 91 | public ReadVarInt () { 92 | new VariableEncodingBenchmark().readVarInt(this); 93 | } 94 | } 95 | 96 | @State(Scope.Thread) 97 | static public class ReadLong extends InputOutputState { 98 | public ReadLong () { 99 | new VariableEncodingBenchmark().writeLong(this); 100 | } 101 | } 102 | 103 | @State(Scope.Thread) 104 | static public class ReadVarLong extends InputOutputState { 105 | public ReadVarLong () { 106 | new VariableEncodingBenchmark().writeVarLong(this); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /build/assembly-all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | all 4 | 5 | zip 6 | 7 | 8 | 9 | . 10 | 11 | README* 12 | LICENCE* 13 | CHANGES* 14 | lib/ 15 | src/ 16 | 17 | 18 | 19 | target 20 | 21 | 22 | *.jar 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /build/commons-lang-2.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/build/commons-lang-2.6.jar -------------------------------------------------------------------------------- /build/junit-platform-console-standalone-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/build/junit-platform-console-standalone-1.8.2.jar -------------------------------------------------------------------------------- /build/settings-sonatype.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sonatype-nexus-snapshots 5 | ${env.SONATYPE_USERNAME} 6 | ${env.SONATYPE_PASSWORD} 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /compat_reports/kryo-2.22.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/compat_reports/kryo-2.22.jar -------------------------------------------------------------------------------- /compat_reports/kryo-2.23.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/compat_reports/kryo-2.23.0.jar -------------------------------------------------------------------------------- /compat_reports/skip-classes.txt: -------------------------------------------------------------------------------- 1 | com.esotericsoftware.kryo.Generics 2 | -------------------------------------------------------------------------------- /eclipse/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /eclipse/.factorypath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /eclipse/.importorder: -------------------------------------------------------------------------------- 1 | # Organize Import Order 2 | # Import this file in Window -> Preferences -> Java -> Code Style -> Organize Imports -> Import... 3 | 0=\# 4 | 1=com.esotericsoftware 5 | 2=java 6 | 3=javax 7 | 4=org 8 | 5= 9 | -------------------------------------------------------------------------------- /eclipse/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kryo 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | 19 | benchmarks 20 | 2 21 | PARENT-1-PROJECT_LOC/benchmarks 22 | 23 | 24 | build 25 | 2 26 | PARENT-1-PROJECT_LOC/build 27 | 28 | 29 | lib 30 | 2 31 | PARENT-1-PROJECT_LOC/lib 32 | 33 | 34 | src 35 | 2 36 | PARENT-1-PROJECT_LOC/src 37 | 38 | 39 | test 40 | 2 41 | PARENT-1-PROJECT_LOC/test 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /eclipse/.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=true 3 | org.eclipse.jdt.apt.genSrcDir=.apt_generated 4 | org.eclipse.jdt.apt.genTestSrcDir=.apt_generated_tests 5 | org.eclipse.jdt.apt.reconcileEnabled=true 6 | -------------------------------------------------------------------------------- /eclipse/.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | formatter_profile=_libgdx 3 | formatter_settings_version=12 4 | -------------------------------------------------------------------------------- /lib/minlog-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/lib/minlog-1.3.1.jar -------------------------------------------------------------------------------- /lib/objenesis-3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/lib/objenesis-3.2.jar -------------------------------------------------------------------------------- /lib/reflectasm-1.11.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/lib/reflectasm-1.11.9.jar -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/ClassResolver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import com.esotericsoftware.kryo.io.Input; 23 | import com.esotericsoftware.kryo.io.Output; 24 | 25 | /** Handles class registration, writing class identifiers to bytes, and reading class identifiers from bytes. 26 | * @author Nathan Sweet */ 27 | public interface ClassResolver { 28 | /** Sets the Kryo instance that this ClassResolver will be used for. This is called automatically by Kryo. */ 29 | public void setKryo (Kryo kryo); 30 | 31 | /** Stores the specified registration. 32 | * @see Kryo#register(Registration) */ 33 | public Registration register (Registration registration); 34 | 35 | /** Removes the registration for the specified ID. 36 | * @return May be null if the class ID was not registered. */ 37 | public Registration unregister (int classID); 38 | 39 | /** Called when an unregistered type is encountered and {@link Kryo#setRegistrationRequired(boolean)} is false. */ 40 | public Registration registerImplicit (Class type); 41 | 42 | /** Returns the registration for the specified class, or null if the class is not registered. */ 43 | public Registration getRegistration (Class type); 44 | 45 | /** Returns the registration for the specified ID, or null if no class is registered with that ID. */ 46 | public Registration getRegistration (int classID); 47 | 48 | /** Writes a class and returns its registration. 49 | * @param type May be null. 50 | * @return Will be null if type is null. */ 51 | public Registration writeClass (Output output, Class type); 52 | 53 | /** Reads a class and returns its registration. 54 | * @return May be null. */ 55 | public Registration readClass (Input input); 56 | 57 | /** Called by {@link Kryo#reset()}. */ 58 | public void reset (); 59 | } 60 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/DefaultSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import com.esotericsoftware.kryo.SerializerFactory.ReflectionSerializerFactory; 23 | 24 | import java.lang.annotation.ElementType; 25 | import java.lang.annotation.Retention; 26 | import java.lang.annotation.RetentionPolicy; 27 | import java.lang.annotation.Target; 28 | 29 | /** Sets the default serializer to use for the annotated class. The specified Serializer class must have a constructor taking a 30 | * Kryo instance and a class, a Kryo instance, a class, or no arguments. 31 | * @see Kryo#register(Class) 32 | * @author Nathan Sweet */ 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target(ElementType.TYPE) 35 | public @interface DefaultSerializer { 36 | /** The serializer class to serialize the annotated type, which will be created by the {@link #serializerFactory()}. Can be 37 | * omitted if the serializer factory knows what type of serializer to create. */ 38 | Class value() default Serializer.class; 39 | 40 | /** The factory used to create the serializer. */ 41 | Class serializerFactory() default ReflectionSerializerFactory.class; 42 | } 43 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/KryoCopyable.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | /** Allows implementing classes to perform their own copying. Hand written copying can be more efficient in some cases. 23 | *

24 | * This method is used instead of the registered serializer's {@link Serializer#copy(Kryo, Object)} method. 25 | * @author Nathan Sweet */ 26 | public interface KryoCopyable { 27 | /** Returns a copy that has the same values as this object. Before Kryo can be used to copy child objects, 28 | * {@link Kryo#reference(Object)} must be called with the copy to ensure it can be referenced by the child objects. 29 | * @see Serializer#copy(Kryo, Object) */ 30 | public T copy (Kryo kryo); 31 | } 32 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/KryoException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | /** General Kryo RuntimeException. 23 | * @author Nathan Sweet */ 24 | public class KryoException extends RuntimeException { 25 | private StringBuffer trace; 26 | 27 | public KryoException () { 28 | super(); 29 | } 30 | 31 | public KryoException (String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | public KryoException (String message) { 36 | super(message); 37 | } 38 | 39 | public KryoException (Throwable cause) { 40 | super(cause); 41 | } 42 | 43 | public String getMessage () { 44 | if (trace == null) return super.getMessage(); 45 | StringBuffer buffer = new StringBuffer(512); 46 | buffer.append(super.getMessage()); 47 | if (buffer.length() > 0) buffer.append('\n'); 48 | buffer.append("Serialization trace:"); 49 | buffer.append(trace); 50 | return buffer.toString(); 51 | } 52 | 53 | /** Adds information to the exception message about where in the the object graph serialization failure occurred. 54 | * {@link Serializer Serializers} can catch {@link KryoException}, add trace information, and rethrow the exception. */ 55 | public void addTrace (String info) { 56 | if (info == null) throw new IllegalArgumentException("info cannot be null."); 57 | if (trace == null) trace = new StringBuffer(512); 58 | trace.append('\n'); 59 | trace.append(info); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/KryoSerializable.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import com.esotericsoftware.kryo.io.Input; 23 | import com.esotericsoftware.kryo.io.Output; 24 | import com.esotericsoftware.kryo.serializers.DefaultSerializers.KryoSerializableSerializer; 25 | 26 | /** Allows implementing classes to perform their own serialization. Hand written serialization can be more efficient in some 27 | * cases. 28 | *

29 | * The default serializer for KryoSerializable is {@link KryoSerializableSerializer}, which uses {@link Kryo#newInstance(Class)} 30 | * to construct the class. 31 | * @author Nathan Sweet */ 32 | public interface KryoSerializable { 33 | public void write (Kryo kryo, Output output); 34 | 35 | public void read (Kryo kryo, Input input); 36 | } 37 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/ReferenceResolver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | /** When references are enabled, this tracks objects that have already been read or written, provides an ID for objects that are 23 | * written, and looks up by ID objects that have been read. 24 | * @author Nathan Sweet */ 25 | public interface ReferenceResolver { 26 | /** Sets the Kryo instance that this ClassResolver will be used for. This is called automatically by Kryo. */ 27 | public void setKryo (Kryo kryo); 28 | 29 | /** Returns an ID for the object if it has been written previously, otherwise returns -1. */ 30 | public int getWrittenId (Object object); 31 | 32 | /** Returns a new ID for an object that is being written for the first time. 33 | * @return The ID, which is stored more efficiently if it is positive and must not be -1 or -2. */ 34 | public int addWrittenObject (Object object); 35 | 36 | /** Reserves the ID for the next object that will be read. This is called only the first time an object is encountered. 37 | * @param type The type of object that will be read. 38 | * @return The ID, which is stored more efficiently if it is positive and must not be -1 or -2. */ 39 | public int nextReadId (Class type); 40 | 41 | /** Sets the ID for an object that has been read. 42 | * @param id The ID from {@link #nextReadId(Class)}. */ 43 | public void setReadObject (int id, Object object); 44 | 45 | /** Returns the object for the specified ID. The ID and object are guaranteed to have been previously passed in a call to 46 | * {@link #setReadObject(int, Object)}. */ 47 | public Object getReadObject (Class type, int id); 48 | 49 | /** Called by {@link Kryo#reset()}. */ 50 | public void reset (); 51 | 52 | /** Returns true if references will be written for the specified type. 53 | * @param type Will never be a primitive type, but may be a primitive type wrapper. */ 54 | public boolean useReferences (Class type); 55 | } 56 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/Registration.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import static com.esotericsoftware.kryo.util.Util.*; 23 | import static com.esotericsoftware.minlog.Log.*; 24 | 25 | import org.objenesis.instantiator.ObjectInstantiator; 26 | 27 | /** Describes the {@link Serializer} and class ID to use for a class. 28 | * @author Nathan Sweet */ 29 | public class Registration { 30 | private final Class type; 31 | private final boolean typeNameAscii; 32 | private final int id; 33 | private Serializer serializer; 34 | private ObjectInstantiator instantiator; 35 | 36 | public Registration (Class type, Serializer serializer, int id) { 37 | if (type == null) throw new IllegalArgumentException("type cannot be null."); 38 | if (serializer == null) throw new IllegalArgumentException("serializer cannot be null."); 39 | this.type = type; 40 | this.serializer = serializer; 41 | this.id = id; 42 | typeNameAscii = isAscii(type.getName()); 43 | } 44 | 45 | public Class getType () { 46 | return type; 47 | } 48 | 49 | public boolean isTypeNameAscii () { 50 | return typeNameAscii; 51 | } 52 | 53 | /** Returns the registered class ID. 54 | * @see Kryo#register(Class) */ 55 | public int getId () { 56 | return id; 57 | } 58 | 59 | public Serializer getSerializer () { 60 | return serializer; 61 | } 62 | 63 | public void setSerializer (Serializer serializer) { 64 | if (serializer == null) throw new IllegalArgumentException("serializer cannot be null."); 65 | this.serializer = serializer; 66 | if (TRACE) trace("kryo", "Update registered serializer: " + type.getName() + " (" + serializer.getClass().getName() + ")"); 67 | } 68 | 69 | /** @return May be null if not yet set. */ 70 | public ObjectInstantiator getInstantiator () { 71 | return instantiator; 72 | } 73 | 74 | /** Sets the instantiator that will create a new instance of the type in {@link Kryo#newInstance(Class)}. */ 75 | public void setInstantiator (ObjectInstantiator instantiator) { 76 | if (instantiator == null) throw new IllegalArgumentException("instantiator cannot be null."); 77 | this.instantiator = instantiator; 78 | } 79 | 80 | public String toString () { 81 | return "[" + id + ", " + className(type) + "]"; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/ByteBufferInputStream.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.nio.Buffer; 25 | import java.nio.ByteBuffer; 26 | 27 | /** An InputStream whose source is a {@link ByteBuffer}. 28 | * @author Nathan Sweet */ 29 | public class ByteBufferInputStream extends InputStream { 30 | private ByteBuffer byteBuffer; 31 | 32 | /** Creates an uninitialized stream that cannot be used until {@link #setByteBuffer(ByteBuffer)} is called. */ 33 | public ByteBufferInputStream () { 34 | } 35 | 36 | /** Creates a stream with a new non-direct buffer of the specified size. The position and limit of the buffer is zero. */ 37 | public ByteBufferInputStream (int bufferSize) { 38 | this(ByteBuffer.allocate(bufferSize)); 39 | flipBuffer(byteBuffer); 40 | } 41 | 42 | public ByteBufferInputStream (ByteBuffer byteBuffer) { 43 | this.byteBuffer = byteBuffer; 44 | } 45 | 46 | public ByteBuffer getByteBuffer () { 47 | return byteBuffer; 48 | } 49 | 50 | public void setByteBuffer (ByteBuffer byteBuffer) { 51 | this.byteBuffer = byteBuffer; 52 | } 53 | 54 | public int read () throws IOException { 55 | if (!byteBuffer.hasRemaining()) return -1; 56 | return byteBuffer.get() & 0xFF; 57 | } 58 | 59 | public int read (byte[] bytes, int offset, int length) throws IOException { 60 | if (length == 0) return 0; 61 | int count = Math.min(byteBuffer.remaining(), length); 62 | if (count == 0) return -1; 63 | byteBuffer.get(bytes, offset, count); 64 | return count; 65 | } 66 | 67 | public int available () throws IOException { 68 | return byteBuffer.remaining(); 69 | } 70 | 71 | private void flipBuffer (Buffer buffer) { 72 | buffer.flip(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/ByteBufferOutputStream.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import java.io.IOException; 23 | import java.io.OutputStream; 24 | import java.nio.ByteBuffer; 25 | 26 | /** An OutputStream whose target is a {@link ByteBuffer}. If bytes would be written that would overflow the buffer, 27 | * {@link #flush()} is called. Subclasses can override flush to empty the buffer. 28 | * @author Nathan Sweet */ 29 | public class ByteBufferOutputStream extends OutputStream { 30 | private ByteBuffer byteBuffer; 31 | 32 | /** Creates an uninitialized stream that cannot be used until {@link #setByteBuffer(ByteBuffer)} is called. */ 33 | public ByteBufferOutputStream () { 34 | } 35 | 36 | /** Creates a stream with a new non-direct buffer of the specified size. */ 37 | public ByteBufferOutputStream (int bufferSize) { 38 | this(ByteBuffer.allocate(bufferSize)); 39 | } 40 | 41 | public ByteBufferOutputStream (ByteBuffer byteBuffer) { 42 | this.byteBuffer = byteBuffer; 43 | } 44 | 45 | public ByteBuffer getByteBuffer () { 46 | return byteBuffer; 47 | } 48 | 49 | public void setByteBuffer (ByteBuffer byteBuffer) { 50 | this.byteBuffer = byteBuffer; 51 | } 52 | 53 | public void write (int b) throws IOException { 54 | if (!byteBuffer.hasRemaining()) flush(); 55 | byteBuffer.put((byte)b); 56 | } 57 | 58 | public void write (byte[] bytes, int offset, int length) throws IOException { 59 | if (byteBuffer.remaining() < length) flush(); 60 | byteBuffer.put(bytes, offset, length); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/InputChunked.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import static com.esotericsoftware.minlog.Log.*; 23 | 24 | import com.esotericsoftware.kryo.KryoException; 25 | 26 | import java.io.IOException; 27 | import java.io.InputStream; 28 | 29 | /** An {@link Input} that reads lengths and chunks of data from another OutputStream, allowing chunks to be skipped. 30 | * @author Nathan Sweet */ 31 | public class InputChunked extends Input { 32 | private int chunkSize = -1; 33 | 34 | /** @see Input#Input() */ 35 | public InputChunked () { 36 | super(); 37 | } 38 | 39 | /** @see Input#Input(int) */ 40 | public InputChunked (int bufferSize) { 41 | super(bufferSize); 42 | } 43 | 44 | /** @see Input#Input(InputStream) */ 45 | public InputChunked (InputStream inputStream) { 46 | super(inputStream); 47 | } 48 | 49 | /** @see Input#Input(InputStream, int) */ 50 | public InputChunked (InputStream inputStream, int bufferSize) { 51 | super(inputStream, bufferSize); 52 | } 53 | 54 | public void setInputStream (InputStream inputStream) { 55 | super.setInputStream(inputStream); 56 | chunkSize = -1; 57 | } 58 | 59 | public void setBuffer (byte[] bytes, int offset, int count) { 60 | super.setBuffer(bytes, offset, count); 61 | chunkSize = -1; 62 | } 63 | 64 | public void reset () { 65 | super.reset(); 66 | chunkSize = -1; 67 | } 68 | 69 | protected int fill (byte[] buffer, int offset, int count) throws KryoException { 70 | if (chunkSize == -1) { // No current chunk, expect a new chunk. 71 | if (!readChunkSize()) return -1; 72 | } else if (chunkSize == 0) // End of chunk. 73 | return -1; 74 | int actual = super.fill(buffer, offset, Math.min(chunkSize, count)); 75 | chunkSize -= actual; 76 | if (chunkSize == 0 && !readChunkSize()) return -1; 77 | return actual; 78 | } 79 | 80 | /** @return false if the end of the stream was reached. */ 81 | private boolean readChunkSize () { 82 | try { 83 | InputStream inputStream = getInputStream(); 84 | for (int offset = 0, result = 0; offset < 32; offset += 7) { 85 | int b = inputStream.read(); 86 | if (b == -1) return false; 87 | result |= (b & 0x7F) << offset; 88 | if ((b & 0x80) == 0) { 89 | chunkSize = result; 90 | if (TRACE && chunkSize > 0) trace("kryo", "Read chunk: " + chunkSize); 91 | return true; 92 | } 93 | } 94 | } catch (IOException ex) { 95 | throw new KryoException("Unable to read chunk size.", ex); 96 | } 97 | throw new KryoException("Unable to read chunk size: malformed integer"); 98 | } 99 | 100 | /** Advances the stream to the next chunk. InputChunked will appear to hit the end of the data until this method is called. */ 101 | public void nextChunk () { 102 | position = limit; // Underflow resets the position to 0. Ensure we are at the end of the chunk. 103 | if (chunkSize == -1) readChunkSize(); // No current chunk, expect a new chunk. 104 | while (chunkSize > 0) 105 | skip(chunkSize); 106 | chunkSize = -1; 107 | if (TRACE) trace("kryo", "Next chunk."); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoBufferOverflowException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import com.esotericsoftware.kryo.KryoException; 23 | 24 | public class KryoBufferOverflowException extends KryoException { 25 | 26 | public KryoBufferOverflowException () { 27 | super(); 28 | } 29 | 30 | public KryoBufferOverflowException (String message, Throwable cause) { 31 | super(message, cause); 32 | } 33 | 34 | public KryoBufferOverflowException (String message) { 35 | super(message); 36 | } 37 | 38 | public KryoBufferOverflowException (Throwable cause) { 39 | super(cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoBufferUnderflowException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import com.esotericsoftware.kryo.KryoException; 23 | 24 | public class KryoBufferUnderflowException extends KryoException { 25 | 26 | public KryoBufferUnderflowException () { 27 | super(); 28 | } 29 | 30 | public KryoBufferUnderflowException (String message, Throwable cause) { 31 | super(message, cause); 32 | } 33 | 34 | public KryoBufferUnderflowException (String message) { 35 | super(message); 36 | } 37 | 38 | public KryoBufferUnderflowException (Throwable cause) { 39 | super(cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoDataInput.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import com.esotericsoftware.kryo.KryoException; 23 | 24 | import java.io.DataInput; 25 | import java.io.EOFException; 26 | import java.io.IOException; 27 | 28 | /** A {@link DataInput} which reads from an {@link Input}. {@link #readLine()} is unsupported. Other methods behave slightly 29 | * differently, eg {@link #readUTF()} may return a null string. 30 | * @author Robert DiFalco */ 31 | public class KryoDataInput implements DataInput, AutoCloseable { 32 | protected Input input; 33 | 34 | public KryoDataInput (Input input) { 35 | this.input = input; 36 | } 37 | 38 | public void setInput (Input input) { 39 | this.input = input; 40 | } 41 | 42 | public void readFully (byte[] b) throws IOException { 43 | readFully(b, 0, b.length); 44 | } 45 | 46 | public void readFully (byte[] b, int off, int len) throws IOException { 47 | try { 48 | input.readBytes(b, off, len); 49 | } catch (KryoException ex) { 50 | throw new EOFException(ex.getMessage()); 51 | } 52 | } 53 | 54 | public int skipBytes (int n) throws IOException { 55 | return (int)input.skip((long)n); 56 | } 57 | 58 | public boolean readBoolean () throws IOException { 59 | return input.readBoolean(); 60 | } 61 | 62 | public byte readByte () throws IOException { 63 | return input.readByte(); 64 | } 65 | 66 | public int readUnsignedByte () throws IOException { 67 | return input.readByteUnsigned(); 68 | } 69 | 70 | public short readShort () throws IOException { 71 | return input.readShort(); 72 | } 73 | 74 | public int readUnsignedShort () throws IOException { 75 | return input.readShortUnsigned(); 76 | } 77 | 78 | public char readChar () throws IOException { 79 | return input.readChar(); 80 | } 81 | 82 | public int readInt () throws IOException { 83 | return input.readInt(); 84 | } 85 | 86 | public long readLong () throws IOException { 87 | return input.readLong(); 88 | } 89 | 90 | public float readFloat () throws IOException { 91 | return input.readFloat(); 92 | } 93 | 94 | public double readDouble () throws IOException { 95 | return input.readDouble(); 96 | } 97 | 98 | /** Not implemented. 99 | * @throws UnsupportedOperationException when called. 100 | * @deprecated this method is not supported in this implementation. */ 101 | public String readLine () throws UnsupportedOperationException { 102 | throw new UnsupportedOperationException(); 103 | } 104 | 105 | /** Reads the length and string of UTF8 characters, or null. This can read strings written by 106 | * {@link KryoDataOutput#writeUTF(String)}, {@link com.esotericsoftware.kryo.io.Output#writeString(String)}, and 107 | * {@link com.esotericsoftware.kryo.io.Output#writeAscii(String)}. 108 | * @return May be null. */ 109 | public String readUTF () throws IOException { 110 | return input.readString(); 111 | } 112 | 113 | public void close () throws Exception { 114 | input.close(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoDataOutput.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import java.io.DataOutput; 23 | import java.io.IOException; 24 | 25 | /** A {@link DataOutput} which writes data to an {@link Output}. 26 | * @author Robert DiFalco */ 27 | public class KryoDataOutput implements DataOutput, AutoCloseable { 28 | protected Output output; 29 | 30 | public KryoDataOutput (Output output) { 31 | this.output = output; 32 | } 33 | 34 | public void setOutput (Output output) { 35 | this.output = output; 36 | } 37 | 38 | public void write (int b) throws IOException { 39 | output.write(b); 40 | } 41 | 42 | public void write (byte[] b) throws IOException { 43 | output.write(b); 44 | } 45 | 46 | public void write (byte[] b, int off, int len) throws IOException { 47 | output.write(b, off, len); 48 | } 49 | 50 | public void writeBoolean (boolean v) throws IOException { 51 | output.writeBoolean(v); 52 | } 53 | 54 | public void writeByte (int v) throws IOException { 55 | output.writeByte(v); 56 | } 57 | 58 | public void writeShort (int v) throws IOException { 59 | output.writeShort(v); 60 | } 61 | 62 | public void writeChar (int v) throws IOException { 63 | output.writeChar((char)v); 64 | } 65 | 66 | public void writeInt (int v) throws IOException { 67 | output.writeInt(v); 68 | } 69 | 70 | public void writeLong (long v) throws IOException { 71 | output.writeLong(v); 72 | } 73 | 74 | public void writeFloat (float v) throws IOException { 75 | output.writeFloat(v); 76 | } 77 | 78 | public void writeDouble (double v) throws IOException { 79 | output.writeDouble(v); 80 | } 81 | 82 | public void writeBytes (String s) throws IOException { 83 | int len = s.length(); 84 | for (int i = 0; i < len; i++) { 85 | output.write((byte)s.charAt(i)); 86 | } 87 | } 88 | 89 | public void writeChars (String s) throws IOException { 90 | int len = s.length(); 91 | for (int i = 0; i < len; i++) { 92 | int v = s.charAt(i); 93 | output.write(v & 0xFF); 94 | output.write((v >>> 8) & 0xFF); 95 | } 96 | } 97 | 98 | public void writeUTF (String s) throws IOException { 99 | output.writeString(s); 100 | } 101 | 102 | public void close () throws Exception { 103 | output.close(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoObjectInput.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | 24 | import java.io.IOException; 25 | import java.io.ObjectInput; 26 | 27 | /** An {@link ObjectInput} which reads data from an {@link Input}. 28 | *

29 | * Note this is not an implementation of {@link java.io.ObjectInputStream} which has special handling for Java serialization, such 30 | * as support for readResolve. 31 | * @author Robert DiFalco */ 32 | public class KryoObjectInput extends KryoDataInput implements ObjectInput { 33 | private final Kryo kryo; 34 | 35 | public KryoObjectInput (Kryo kryo, Input input) { 36 | super(input); 37 | this.kryo = kryo; 38 | } 39 | 40 | public Object readObject () throws ClassNotFoundException, IOException { 41 | return kryo.readClassAndObject(input); 42 | } 43 | 44 | public int read () throws IOException { 45 | return input.read(); 46 | } 47 | 48 | public int read (byte[] b) throws IOException { 49 | return input.read(b); 50 | } 51 | 52 | public int read (byte[] b, int off, int len) throws IOException { 53 | return input.read(b, off, len); 54 | } 55 | 56 | public long skip (long n) throws IOException { 57 | return input.skip(n); 58 | } 59 | 60 | public int available () throws IOException { 61 | return 0; 62 | } 63 | 64 | public void close () throws IOException { 65 | input.close(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/KryoObjectOutput.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | 24 | import java.io.IOException; 25 | import java.io.ObjectOutput; 26 | 27 | /** An {@link java.io.ObjectOutput} which writes data to an {@link Output}. 28 | *

29 | * Note this is not an implementation of {@link java.io.ObjectOutputStream} which has special handling for Java serialization and 30 | * serialization extras like writeReplace. By default it will simply delegate to the appropriate Kryo method. Also, using it will 31 | * currently add one extra byte for each time {@link #writeObject(Object)} is invoked since we need to allow unknown null objects. 32 | * @author Robert DiFalco */ 33 | public class KryoObjectOutput extends KryoDataOutput implements ObjectOutput { 34 | private final Kryo kryo; 35 | 36 | public KryoObjectOutput (Kryo kryo, Output output) { 37 | super(output); 38 | this.kryo = kryo; 39 | } 40 | 41 | public void writeObject (Object object) throws IOException { 42 | kryo.writeClassAndObject(output, object); 43 | } 44 | 45 | public void flush () throws IOException { 46 | output.flush(); 47 | } 48 | 49 | public void close () throws IOException { 50 | output.close(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/io/OutputChunked.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import static com.esotericsoftware.kryo.util.Util.*; 23 | import static com.esotericsoftware.minlog.Log.*; 24 | 25 | import com.esotericsoftware.kryo.KryoException; 26 | 27 | import java.io.IOException; 28 | import java.io.OutputStream; 29 | 30 | /** An {@link Output} that writes the length before each flush. The length allows the chunks to be skipped when reading. 31 | * @author Nathan Sweet */ 32 | public class OutputChunked extends Output { 33 | /** @see Output#Output() */ 34 | public OutputChunked () { 35 | super(); 36 | } 37 | 38 | /** @see Output#Output(int) */ 39 | public OutputChunked (int bufferSize) { 40 | super(bufferSize); 41 | } 42 | 43 | /** @see Output#Output(OutputStream) */ 44 | public OutputChunked (OutputStream outputStream) { 45 | super(outputStream); 46 | } 47 | 48 | /** @see Output#Output(OutputStream, int) */ 49 | public OutputChunked (OutputStream outputStream, int bufferSize) { 50 | super(outputStream, bufferSize); 51 | } 52 | 53 | public void flush () throws KryoException { 54 | if (position() > 0) { 55 | try { 56 | writeChunkSize(); 57 | super.flush(); 58 | } catch (IOException ex) { 59 | throw new KryoException(ex); 60 | } 61 | } else { 62 | super.flush(); 63 | } 64 | } 65 | 66 | private void writeChunkSize () throws IOException { 67 | int size = position(); 68 | if (TRACE) trace("kryo", "Write chunk: " + size + pos(size)); 69 | OutputStream outputStream = getOutputStream(); 70 | if ((size & ~0x7F) == 0) { 71 | outputStream.write(size); 72 | return; 73 | } 74 | outputStream.write((size & 0x7F) | 0x80); 75 | size >>>= 7; 76 | if ((size & ~0x7F) == 0) { 77 | outputStream.write(size); 78 | return; 79 | } 80 | outputStream.write((size & 0x7F) | 0x80); 81 | size >>>= 7; 82 | if ((size & ~0x7F) == 0) { 83 | outputStream.write(size); 84 | return; 85 | } 86 | outputStream.write((size & 0x7F) | 0x80); 87 | size >>>= 7; 88 | if ((size & ~0x7F) == 0) { 89 | outputStream.write(size); 90 | return; 91 | } 92 | outputStream.write((size & 0x7F) | 0x80); 93 | size >>>= 7; 94 | outputStream.write(size); 95 | } 96 | 97 | /** Marks the current written data as the end of a chunk. This chunk can then be skipped when reading. */ 98 | public void endChunk () { 99 | flush(); 100 | if (TRACE) trace("kryo", "End chunk."); 101 | try { 102 | getOutputStream().write(0); // Zero length chunk. 103 | } catch (IOException ex) { 104 | throw new KryoException(ex); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/BlowfishSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.KryoException; 24 | import com.esotericsoftware.kryo.Serializer; 25 | import com.esotericsoftware.kryo.io.Input; 26 | import com.esotericsoftware.kryo.io.Output; 27 | 28 | import java.io.IOException; 29 | 30 | import javax.crypto.Cipher; 31 | import javax.crypto.CipherInputStream; 32 | import javax.crypto.CipherOutputStream; 33 | import javax.crypto.spec.SecretKeySpec; 34 | 35 | /** Encrypts data using the blowfish cipher. 36 | * @author Nathan Sweet */ 37 | public class BlowfishSerializer extends Serializer { 38 | private final Serializer serializer; 39 | private static SecretKeySpec keySpec; 40 | 41 | public BlowfishSerializer (Serializer serializer, byte[] key) { 42 | this.serializer = serializer; 43 | keySpec = new SecretKeySpec(key, "Blowfish"); 44 | } 45 | 46 | public void write (Kryo kryo, Output output, Object object) { 47 | Cipher cipher = getCipher(Cipher.ENCRYPT_MODE); 48 | CipherOutputStream cipherStream = new CipherOutputStream(output, cipher); 49 | Output cipherOutput = new Output(cipherStream, 256) { 50 | public void close () throws KryoException { 51 | // Don't allow the CipherOutputStream to close the output. 52 | } 53 | }; 54 | serializer.write(kryo, cipherOutput, object); 55 | cipherOutput.flush(); 56 | try { 57 | cipherStream.close(); 58 | } catch (IOException ex) { 59 | throw new KryoException(ex); 60 | } 61 | } 62 | 63 | public Object read (Kryo kryo, Input input, Class type) { 64 | Cipher cipher = getCipher(Cipher.DECRYPT_MODE); 65 | CipherInputStream cipherInput = new CipherInputStream(input, cipher); 66 | return serializer.read(kryo, new Input(cipherInput, 256), type); 67 | } 68 | 69 | public Object copy (Kryo kryo, Object original) { 70 | return serializer.copy(kryo, original); 71 | } 72 | 73 | private static Cipher getCipher (int mode) { 74 | try { 75 | Cipher cipher = Cipher.getInstance("Blowfish"); 76 | cipher.init(mode, keySpec); 77 | return cipher; 78 | } catch (Exception ex) { 79 | throw new KryoException(ex); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/DeflateSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.KryoException; 24 | import com.esotericsoftware.kryo.Serializer; 25 | import com.esotericsoftware.kryo.io.Input; 26 | import com.esotericsoftware.kryo.io.InputChunked; 27 | import com.esotericsoftware.kryo.io.Output; 28 | import com.esotericsoftware.kryo.io.OutputChunked; 29 | 30 | import java.io.IOException; 31 | import java.util.zip.Deflater; 32 | import java.util.zip.DeflaterOutputStream; 33 | import java.util.zip.Inflater; 34 | import java.util.zip.InflaterInputStream; 35 | 36 | public class DeflateSerializer extends Serializer { 37 | private final Serializer serializer; 38 | private boolean noHeaders = true; 39 | private int compressionLevel = 4; 40 | 41 | public DeflateSerializer (Serializer serializer) { 42 | this.serializer = serializer; 43 | } 44 | 45 | public void write (Kryo kryo, Output output, Object object) { 46 | OutputChunked outputChunked = new OutputChunked(output, 256); 47 | Deflater deflater = new Deflater(compressionLevel, noHeaders); 48 | try { 49 | DeflaterOutputStream deflaterStream = new DeflaterOutputStream(outputChunked, deflater); 50 | Output deflaterOutput = new Output(deflaterStream, 256); 51 | serializer.write(kryo, deflaterOutput, object); 52 | deflaterOutput.flush(); 53 | deflaterStream.finish(); 54 | } catch (IOException ex) { 55 | throw new KryoException(ex); 56 | } finally { 57 | deflater.end(); 58 | } 59 | outputChunked.endChunk(); 60 | } 61 | 62 | public Object read (Kryo kryo, Input input, Class type) { 63 | // The inflater would read from input beyond the compressed bytes if chunked enoding wasn't used. 64 | Inflater inflater = new Inflater(noHeaders); 65 | try { 66 | InflaterInputStream inflaterStream = new InflaterInputStream(new InputChunked(input, 256), inflater); 67 | return serializer.read(kryo, new Input(inflaterStream, 256), type); 68 | } finally { 69 | inflater.end(); 70 | } 71 | } 72 | 73 | public void setNoHeaders (boolean noHeaders) { 74 | this.noHeaders = noHeaders; 75 | } 76 | 77 | /** Default is 4. 78 | * @see Deflater#setLevel(int) */ 79 | public void setCompressionLevel (int compressionLevel) { 80 | this.compressionLevel = compressionLevel; 81 | } 82 | 83 | public Object copy (Kryo kryo, Object original) { 84 | return serializer.copy(kryo, original); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/EnumMapSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.io.Input; 24 | 25 | import java.util.EnumMap; 26 | 27 | /** @author Nathan Sweet */ 28 | public class EnumMapSerializer extends MapSerializer { 29 | private final Class enumType; 30 | 31 | public EnumMapSerializer (Class enumType) { 32 | this.enumType = enumType; 33 | } 34 | 35 | protected EnumMap create (Kryo kryo, Input input, Class type, int size) { 36 | return new EnumMap(enumType); 37 | } 38 | 39 | protected EnumMap createCopy (Kryo kryo, EnumMap original) { 40 | return new EnumMap(original); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/EnumNameSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.KryoException; 24 | import com.esotericsoftware.kryo.io.Input; 25 | import com.esotericsoftware.kryo.io.Output; 26 | 27 | /** Serializes enums using the enum's name. This prevents invalidating previously serialized byts when the enum order changes. 28 | * @author KwonNam Son */ 29 | public class EnumNameSerializer extends ImmutableSerializer { 30 | private final Class enumType; 31 | 32 | public EnumNameSerializer (Class enumType) { 33 | this.enumType = enumType; 34 | } 35 | 36 | public void write (Kryo kryo, Output output, Enum object) { 37 | output.writeString(object.name()); 38 | } 39 | 40 | public Enum read (Kryo kryo, Input input, Class type) { 41 | String name = input.readString(); 42 | try { 43 | return Enum.valueOf(enumType, name); 44 | } catch (IllegalArgumentException ex) { 45 | throw new KryoException("Enum value not found with name: " + name, ex); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/ImmutableSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Serializer; 23 | 24 | /** A serializer which has {@link #setImmutable(boolean)} set to true. This convenience class exists only to reduce the typing 25 | * needed to define a serializer which is immutable. 26 | * @author Nathan Sweet */ 27 | public abstract class ImmutableSerializer extends Serializer { 28 | { 29 | setImmutable(true); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/serializers/JavaSerializer.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.KryoException; 24 | import com.esotericsoftware.kryo.KryoSerializable; 25 | import com.esotericsoftware.kryo.Serializer; 26 | import com.esotericsoftware.kryo.io.Input; 27 | import com.esotericsoftware.kryo.io.Output; 28 | import com.esotericsoftware.kryo.util.ObjectMap; 29 | 30 | import java.io.IOException; 31 | import java.io.InputStream; 32 | import java.io.ObjectInputStream; 33 | import java.io.ObjectOutputStream; 34 | import java.io.ObjectStreamClass; 35 | 36 | /** Serializes objects using Java's built in serialization mechanism. Note that this is very inefficient and should be avoided if 37 | * possible. 38 | * @see Serializer 39 | * @see FieldSerializer 40 | * @see KryoSerializable 41 | * @author Nathan Sweet */ 42 | public class JavaSerializer extends Serializer { 43 | public void write (Kryo kryo, Output output, Object object) { 44 | try { 45 | ObjectMap graphContext = kryo.getGraphContext(); 46 | ObjectOutputStream objectStream = (ObjectOutputStream)graphContext.get(this); 47 | if (objectStream == null) { 48 | objectStream = new ObjectOutputStream(output); 49 | graphContext.put(this, objectStream); 50 | } 51 | objectStream.writeObject(object); 52 | objectStream.flush(); 53 | } catch (Exception ex) { 54 | throw new KryoException("Error during Java serialization.", ex); 55 | } 56 | } 57 | 58 | public Object read (Kryo kryo, Input input, Class type) { 59 | try { 60 | ObjectMap graphContext = kryo.getGraphContext(); 61 | ObjectInputStream objectStream = (ObjectInputStream)graphContext.get(this); 62 | if (objectStream == null) { 63 | objectStream = new ObjectInputStreamWithKryoClassLoader(input, kryo); 64 | graphContext.put(this, objectStream); 65 | } 66 | return objectStream.readObject(); 67 | } catch (Exception ex) { 68 | throw new KryoException("Error during Java deserialization.", ex); 69 | } 70 | } 71 | 72 | /** {@link ObjectInputStream} uses the last user-defined {@link ClassLoader}, which may not be the correct one. This is a known 73 | * Java issue and is often solved by using a specific class loader. See: 74 | * https://github.com/apache/spark/blob/v1.6.3/streaming/src/main/scala/org/apache/spark/streaming/Checkpoint.scala#L154 75 | * https://issues.apache.org/jira/browse/GROOVY-1627 */ 76 | private static class ObjectInputStreamWithKryoClassLoader extends ObjectInputStream { 77 | private final Kryo kryo; 78 | 79 | ObjectInputStreamWithKryoClassLoader (InputStream in, Kryo kryo) throws IOException { 80 | super(in); 81 | this.kryo = kryo; 82 | } 83 | 84 | protected Class resolveClass (ObjectStreamClass type) { 85 | try { 86 | return Class.forName(type.getName(), false, kryo.getClassLoader()); 87 | } catch (ClassNotFoundException ignored) {} 88 | try { 89 | return super.resolveClass(type); 90 | } catch (ClassNotFoundException ex) { 91 | throw new KryoException("Class not found: " + type.getName(), ex); 92 | } catch (IOException ex) { 93 | throw new KryoException("Could not load class: " + type.getName(), ex); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/HashMapReferenceResolver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.ReferenceResolver; 24 | 25 | import java.util.ArrayList; 26 | import java.util.IdentityHashMap; 27 | 28 | /** Uses an {@link IdentityHashMap} to track objects that have already been written. This can handle a graph with any number of 29 | * objects, but is slightly slower than {@link MapReferenceResolver} because IdentityHashMap allocates on put and slower slower 30 | * than {@link ListReferenceResolver} for graphs with few objects. 31 | * @author Nathan Sweet */ 32 | public class HashMapReferenceResolver implements ReferenceResolver { 33 | protected Kryo kryo; 34 | protected final IdentityHashMap writtenObjects = new IdentityHashMap(); 35 | protected final ArrayList readObjects = new ArrayList(); 36 | 37 | public void setKryo (Kryo kryo) { 38 | this.kryo = kryo; 39 | } 40 | 41 | public int addWrittenObject (Object object) { 42 | int id = writtenObjects.size(); 43 | writtenObjects.put(object, id); 44 | return id; 45 | } 46 | 47 | public int getWrittenId (Object object) { 48 | Integer id = writtenObjects.get(object); 49 | if (id == null) return -1; 50 | return id; 51 | } 52 | 53 | public int nextReadId (Class type) { 54 | int id = readObjects.size(); 55 | readObjects.add(null); 56 | return id; 57 | } 58 | 59 | public void setReadObject (int id, Object object) { 60 | readObjects.set(id, object); 61 | } 62 | 63 | public Object getReadObject (Class type, int id) { 64 | return readObjects.get(id); 65 | } 66 | 67 | public void reset () { 68 | readObjects.clear(); 69 | writtenObjects.clear(); 70 | } 71 | 72 | /** Returns false for all primitive wrappers and enums. */ 73 | public boolean useReferences (Class type) { 74 | return !Util.isWrapperClass(type) && !Util.isEnum(type); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/IdentityObjectIntMap.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | /** An unordered map where identity comparison is used for the objects keys and the values are unboxed ints. Null keys are not 23 | * allowed. No allocation is done except when growing the table size. 24 | *

25 | * This class performs fast contains and remove (typically O(1), worst case O(n) but that is rare in practice). Add may be 26 | * slightly slower, depending on hash collisions. Load factors greater than 0.91 greatly increase the chances to resize to the 27 | * next higher POT size. 28 | *

29 | * Unordered sets and maps are not designed to provide especially fast iteration. 30 | *

31 | * This implementation uses linear probing with the backward shift algorithm for removal. Linear probing continues to work even 32 | * when all hashCodes collide, just more slowly. 33 | * @author Nathan Sweet 34 | * @author Tommy Ettinger */ 35 | public class IdentityObjectIntMap extends ObjectIntMap { 36 | /** Creates a new map with an initial capacity of 51 and a load factor of 0.8. */ 37 | public IdentityObjectIntMap () { 38 | super(); 39 | } 40 | 41 | /** Creates a new map with a load factor of 0.8. 42 | * @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */ 43 | public IdentityObjectIntMap (int initialCapacity) { 44 | super(initialCapacity); 45 | } 46 | 47 | /** Creates a new map with the specified initial capacity and load factor. This map will hold initialCapacity items before 48 | * growing the backing table. 49 | * @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */ 50 | public IdentityObjectIntMap (int initialCapacity, float loadFactor) { 51 | super(initialCapacity, loadFactor); 52 | } 53 | 54 | /** Creates a new map identical to the specified map. */ 55 | public IdentityObjectIntMap (IdentityObjectIntMap map) { 56 | super(map); 57 | } 58 | 59 | protected int place (K item) { 60 | return System.identityHashCode(item) & mask; 61 | } 62 | 63 | public int get (K key, int defaultValue) { 64 | for (int i = place(key);; i = i + 1 & mask) { 65 | K other = keyTable[i]; 66 | if (other == null) return defaultValue; 67 | if (other == key) return valueTable[i]; 68 | } 69 | } 70 | 71 | int locateKey (K key) { 72 | if (key == null) throw new IllegalArgumentException("key cannot be null."); 73 | K[] keyTable = this.keyTable; 74 | for (int i = place(key);; i = i + 1 & mask) { 75 | K other = keyTable[i]; 76 | if (other == null) return -(i + 1); // Empty space is available. 77 | if (other == key) return i; // Same key was found. 78 | } 79 | } 80 | 81 | public int hashCode () { 82 | int h = size; 83 | K[] keyTable = this.keyTable; 84 | int[] valueTable = this.valueTable; 85 | for (int i = 0, n = keyTable.length; i < n; i++) { 86 | K key = keyTable[i]; 87 | if (key != null) h += System.identityHashCode(key) + valueTable[i]; 88 | } 89 | return h; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/ListReferenceResolver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.ReferenceResolver; 24 | 25 | import java.util.ArrayList; 26 | 27 | /** Uses an {@link ArrayList} to track objects that have already been written. This is more efficient than 28 | * {@link MapReferenceResolver} for graphs with few objects, providing an approximate 15% increase in deserialization speed. This 29 | * should not be used for graphs with many objects because it uses a linear look up to find objects that have already been 30 | * written. 31 | * @author Nathan Sweet */ 32 | public class ListReferenceResolver implements ReferenceResolver { 33 | protected Kryo kryo; 34 | protected final ArrayList seenObjects = new ArrayList(); 35 | 36 | public void setKryo (Kryo kryo) { 37 | this.kryo = kryo; 38 | } 39 | 40 | public int addWrittenObject (Object object) { 41 | int id = seenObjects.size(); 42 | seenObjects.add(object); 43 | return id; 44 | } 45 | 46 | public int getWrittenId (Object object) { 47 | for (int i = 0, n = seenObjects.size(); i < n; i++) 48 | if (seenObjects.get(i) == object) return i; 49 | return -1; 50 | } 51 | 52 | public int nextReadId (Class type) { 53 | int id = seenObjects.size(); 54 | seenObjects.add(null); 55 | return id; 56 | } 57 | 58 | public void setReadObject (int id, Object object) { 59 | seenObjects.set(id, object); 60 | } 61 | 62 | public Object getReadObject (Class type, int id) { 63 | return seenObjects.get(id); 64 | } 65 | 66 | public void reset () { 67 | seenObjects.clear(); 68 | } 69 | 70 | /** Returns false for all primitive wrappers and enums. */ 71 | public boolean useReferences (Class type) { 72 | return !Util.isWrapperClass(type) && !Util.isEnum(type); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/MapReferenceResolver.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import com.esotericsoftware.kryo.Kryo; 23 | import com.esotericsoftware.kryo.ReferenceResolver; 24 | 25 | import java.util.ArrayList; 26 | 27 | /** Uses an {@link IdentityObjectIntMap} to track objects that have already been written. This can handle a graph with any number 28 | * of objects, but is slightly slower than {@link ListReferenceResolver} for graphs with few objects. Compared to 29 | * {@link HashMapReferenceResolver}, this may provide better performance since the IdentityObjectIntMap does not normally allocate 30 | * for get or put. 31 | * @author Nathan Sweet */ 32 | public class MapReferenceResolver implements ReferenceResolver { 33 | private static final int DEFAULT_CAPACITY = 2048; 34 | 35 | protected Kryo kryo; 36 | protected final IdentityObjectIntMap writtenObjects = new IdentityObjectIntMap<>(); 37 | protected final ArrayList readObjects = new ArrayList<>(); 38 | private final int maximumCapacity; 39 | 40 | /** Creates a reference resolver with a default maximum capacity of 2048 */ 41 | public MapReferenceResolver () { 42 | this(DEFAULT_CAPACITY); 43 | } 44 | 45 | /** Creates a reference resolver with the specified maximum capacity. The default value of 2048 is good enough in most cases. 46 | * If the average object graph is larger than the default, increasing this value can provide better performance. 47 | * @param maximumCapacity the capacity to trim written and read objects to when {@link #reset()} is called */ 48 | public MapReferenceResolver (int maximumCapacity) { 49 | this.maximumCapacity = maximumCapacity; 50 | } 51 | 52 | public void setKryo (Kryo kryo) { 53 | this.kryo = kryo; 54 | } 55 | 56 | public int addWrittenObject (Object object) { 57 | int id = writtenObjects.size; 58 | writtenObjects.put(object, id); 59 | return id; 60 | } 61 | 62 | public int getWrittenId (Object object) { 63 | return writtenObjects.get(object, -1); 64 | } 65 | 66 | public int nextReadId (Class type) { 67 | int id = readObjects.size(); 68 | readObjects.add(null); 69 | return id; 70 | } 71 | 72 | public void setReadObject (int id, Object object) { 73 | readObjects.set(id, object); 74 | } 75 | 76 | public Object getReadObject (Class type, int id) { 77 | return readObjects.get(id); 78 | } 79 | 80 | public void reset () { 81 | final int size = readObjects.size(); 82 | readObjects.clear(); 83 | if (size > maximumCapacity) { 84 | readObjects.trimToSize(); 85 | readObjects.ensureCapacity(maximumCapacity); 86 | } 87 | writtenObjects.clear(maximumCapacity); 88 | } 89 | 90 | /** Returns false for all primitive wrappers and enums. */ 91 | public boolean useReferences (Class type) { 92 | return !Util.isWrapperClass(type) && !Util.isEnum(type); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/NoGenerics.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import java.lang.reflect.TypeVariable; 23 | 24 | /** Implementation of {@link Generics} that does not store generic type arguments and actual classes for type variables. */ 25 | public final class NoGenerics implements Generics { 26 | 27 | public static final Generics INSTANCE = new NoGenerics(); 28 | 29 | private NoGenerics () { 30 | // singleton 31 | } 32 | 33 | @Override 34 | public GenericsHierarchy buildHierarchy (Class type) { 35 | return GenericsHierarchy.EMPTY; 36 | } 37 | 38 | @Override 39 | public void pushGenericType (GenericType fieldType) { 40 | } 41 | 42 | @Override 43 | public void popGenericType () { 44 | } 45 | 46 | @Override 47 | public GenericType[] nextGenericTypes () { 48 | return null; 49 | } 50 | 51 | @Override 52 | public Class nextGenericClass () { 53 | return null; 54 | } 55 | 56 | @Override 57 | public int pushTypeVariables (GenericsHierarchy hierarchy, GenericType[] args) { 58 | return 0; 59 | } 60 | 61 | @Override 62 | public void popTypeVariables (int count) { 63 | } 64 | 65 | @Override 66 | public Class resolveTypeVariable (TypeVariable typeVariable) { 67 | return null; 68 | } 69 | 70 | @Override 71 | public int getGenericTypesSize () { 72 | return 0; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/com/esotericsoftware/kryo/util/Null.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import java.lang.annotation.Documented; 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Target; 25 | 26 | /** An element with this annotation claims that the element may have a {@code null} value. Apart from documentation purposes this 27 | * annotation is intended to be used by static analysis tools to validate against probable runtime errors or contract violations. 28 | * @author maltaisn */ 29 | @Documented 30 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) 31 | public @interface Null { 32 | } 33 | -------------------------------------------------------------------------------- /test-jdk11/com/esotericsoftware/kryo/TestDataJava11.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import com.esotericsoftware.kryo.SerializationCompatTestData; 23 | 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.Set; 27 | 28 | public class TestDataJava11 extends SerializationCompatTestData.TestData { 29 | private List emptyImmutableList; 30 | private Map emptyImmutableMap; 31 | private Set emptyImmutableSet; 32 | private List singleImmutableList; 33 | private Map singleImmutableMap; 34 | private Set singleImmutableSet; 35 | private List immutableList; 36 | private Map immutableMap; 37 | private Set immutableSet; 38 | 39 | public TestDataJava11 () { 40 | emptyImmutableList = List.of(); 41 | emptyImmutableMap = Map.of(); 42 | emptyImmutableSet = Set.of(); 43 | singleImmutableList = List.of(42); 44 | singleImmutableMap = Map.of(42, 42); 45 | singleImmutableSet = Set.of(42); 46 | immutableList = List.of(1, 2, 3); 47 | immutableMap = Map.of(1, 2, 3, 4); 48 | immutableSet = Set.of(1, 2, 3); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test-jdk11/com/esotericsoftware/kryo/serializers/ImmutableCollectionsSerializersTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.Objects; 28 | import java.util.Set; 29 | 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | 33 | /** Test for java >=9 ImmutableCollections serializers. */ 34 | class ImmutableCollectionsSerializersTest extends KryoTestCase { 35 | { 36 | supportsCopy = true; 37 | } 38 | 39 | @BeforeEach 40 | public void setUp () throws Exception { 41 | super.setUp(); 42 | 43 | ImmutableCollectionsSerializers.registerSerializers(kryo); 44 | kryo.register(HashMap.class); 45 | kryo.register(TestClass.class); 46 | } 47 | 48 | @Test 49 | void testImmutableCollections () { 50 | roundTrip(4, new TestClass(null, null, null)); 51 | roundTrip(7, new TestClass(List.of(), Map.of(), Set.of())); 52 | roundTrip(11, new TestClass(List.of(1), Map.of(1, 2), Set.of(1))); 53 | roundTrip(17, new TestClass(List.of(1, 2, 3), Map.of(1, 2, 3, 4), Set.of(1, 2, 3))); 54 | } 55 | 56 | @Test 57 | void testImmutableList () { 58 | roundTrip(2, List.of()); 59 | roundTrip(4, List.of(1)); 60 | roundTrip(5, List.of(1, 2)); 61 | roundTrip(6, List.of(1, 2, 3)); 62 | roundTrip(4, List.of(1, 2, 3).subList(0, 1)); 63 | } 64 | 65 | @Test 66 | void setImmutableMap () { 67 | roundTrip(2, Map.of()); 68 | roundTrip(6, Map.of(1, 2)); 69 | roundTrip(10, Map.of(1, 2, 3, 4)); 70 | } 71 | 72 | @Test 73 | void testImmutableSet () { 74 | roundTrip(2, Set.of()); 75 | roundTrip(4, Set.of(1)); 76 | roundTrip(5, Set.of(1, 2)); 77 | roundTrip(6, Set.of(1, 2, 3)); 78 | } 79 | 80 | public static class TestClass { 81 | List list; 82 | Map map; 83 | Set set; 84 | 85 | public TestClass () { 86 | } 87 | 88 | public TestClass (List list, Map map, Set set) { 89 | this.list = list; 90 | this.map = map; 91 | this.set = set; 92 | } 93 | 94 | @Override 95 | public boolean equals (Object o) { 96 | if (this == o) return true; 97 | if (o == null || getClass() != o.getClass()) return false; 98 | final TestClass testClass = (TestClass)o; 99 | return Objects.equals(list, testClass.list) && Objects.equals(map, testClass.map) 100 | && Objects.equals(set, testClass.set); 101 | } 102 | 103 | @Override 104 | public int hashCode () { 105 | return Objects.hash(list, map, set); 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /test-jdk17/com/esotericsoftware/kryo/TestDataJava17.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import org.apache.commons.lang3.builder.EqualsBuilder; 23 | import org.apache.commons.lang3.builder.HashCodeBuilder; 24 | 25 | /** Test data for {@link com.esotericsoftware.kryo.serializers.RecordSerializerTest}. 26 | * @author Julia Boes 27 | * @author Chris Hegarty 28 | */ 29 | public class TestDataJava17 extends SerializationCompatTestData.TestData { 30 | public record Rec (byte b, short s, int i, long l, float f, double d, boolean bool, char c, String str, Integer[] n) { 31 | // Overriden because of https://stackoverflow.com/questions/61261226/java-14-records-and-arrays 32 | public boolean equals(Object o) { 33 | return EqualsBuilder.reflectionEquals(this, o); 34 | } 35 | 36 | public int hashCode() { 37 | return HashCodeBuilder.reflectionHashCode(this); 38 | } 39 | }; 40 | 41 | private Rec rec; 42 | 43 | public TestDataJava17() { 44 | rec = new Rec("b".getBytes()[0], (short)1, 2, 3L, 4.0f, 5.0d, true, 'c', "foo", new Integer[]{1,2,3}); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test-kotlin/com.esotericsoftware.kryo/SerializationTest.kt: -------------------------------------------------------------------------------- 1 | package com.esotericsoftware.kryo 2 | 3 | import com.esotericsoftware.kryo.io.Input 4 | import com.esotericsoftware.kryo.io.Output 5 | import org.junit.jupiter.api.Assertions.assertEquals 6 | import org.junit.jupiter.api.Assertions.assertNotSame 7 | import org.junit.jupiter.api.Test 8 | 9 | class SerializationTest { 10 | 11 | // https://github.com/EsotericSoftware/kryo/issues/864 12 | @Test 13 | fun testLambda() { 14 | val kryo = Kryo().apply { 15 | isRegistrationRequired = false 16 | } 17 | 18 | val example = Example() 19 | 20 | val bytes = Output(1024).use { output -> 21 | kryo.writeClassAndObject(output, example) 22 | output.toBytes() 23 | } 24 | 25 | val deserialized = Input(bytes).use { input -> 26 | kryo.readClassAndObject(input) 27 | } 28 | 29 | assertEquals(example::class.java, deserialized::class.java) 30 | assertNotSame(example, deserialized) 31 | } 32 | 33 | class Example(private val p: (Long) -> String) { 34 | constructor() : this(@JvmSerializableLambda { it.toString() }) 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/DefaultInstantiatorStrategyTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2025, Daniel Pavlov 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertThrows; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | 29 | public class DefaultInstantiatorStrategyTest { 30 | 31 | DefaultInstantiatorStrategy instantiatorStrategy = new DefaultInstantiatorStrategy(); 32 | 33 | @Test 34 | public void testAbstractStaticMemberClassCannotBeInstantiated() { 35 | KryoException thrown = assertThrows(KryoException.class, () -> tryInstantiate(AbstractStaticMemberClass.class)); 36 | assertTrue(thrown.getMessage().contains("The type you are trying to serialize into is abstract.")); 37 | } 38 | 39 | @Test 40 | public void testInterfaceMemberClassCannotBeInstantiated() { 41 | KryoException thrown = assertThrows(KryoException.class, () -> tryInstantiate(MemberInterface.class)); 42 | assertTrue(thrown.getMessage().contains("The type you are trying to serialize into is abstract (interface).")); 43 | } 44 | 45 | @Test 46 | public void testAbstractClassCannotBeInstantiated() { 47 | KryoException thrown = assertThrows(KryoException.class, () -> tryInstantiate(AbstracClass.class)); 48 | assertTrue(thrown.getMessage().contains("The type you are trying to serialize into is abstract.")); 49 | } 50 | 51 | @Test 52 | public void testInterfaceClassCannotBeInstantiated() { 53 | KryoException thrown = assertThrows(KryoException.class, () -> tryInstantiate(InterfaceClass.class)); 54 | assertTrue(thrown.getMessage().contains("The type you are trying to serialize into is abstract (interface).")); 55 | } 56 | 57 | public void tryInstantiate(Class type) { 58 | instantiatorStrategy.newInstantiatorOf(type).newInstance(); 59 | } 60 | 61 | private static abstract class AbstractStaticMemberClass {} 62 | 63 | private interface MemberInterface {} 64 | } 65 | 66 | abstract class AbstracClass {} 67 | 68 | interface InterfaceClass {} -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/DepthTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import org.junit.jupiter.api.Test; 23 | 24 | class DepthTest extends KryoTestCase { 25 | static class Node { 26 | Node child; 27 | 28 | public boolean equals (Object obj) { 29 | return true; 30 | } 31 | } 32 | 33 | @Test 34 | void testDepth () { 35 | Node current = new Node<>(); 36 | Node root = current; 37 | for (int i = 0; i < 300; i++) { 38 | current.child = new Node(); 39 | current = current.child; 40 | } 41 | kryo.register(Node.class); 42 | roundTrip(302, root); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/GarbageCollectionTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.util.DefaultClassResolver; 25 | import com.esotericsoftware.kryo.util.MapReferenceResolver; 26 | 27 | import java.lang.ref.WeakReference; 28 | 29 | import org.junit.jupiter.api.Test; 30 | 31 | /** Tests for detecting PermGen memory leaks. 32 | * @author Tumi */ 33 | class GarbageCollectionTest { 34 | @Test 35 | void test () { 36 | Kryo kryo = new Kryo(new DefaultClassResolver(), new MapReferenceResolver()); 37 | WeakReference kryoWeakRef = new WeakReference(kryo); 38 | kryo = null; // remove strong ref, now kryo is only weak-reachable 39 | reclaim(kryoWeakRef); 40 | } 41 | 42 | private void reclaim (WeakReference kryoWeakRef) { 43 | // Forces GC 44 | System.gc(); 45 | // Waits for recaim the weaked-reachable kryo instance 46 | int times = 0; 47 | while (kryoWeakRef.get() != null && times < 30) { // limit 3 seconds 48 | try { 49 | Thread.sleep(100); 50 | } catch (InterruptedException ignored) { 51 | } 52 | times++; 53 | } 54 | assertNull(kryoWeakRef.get()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/KryoAssert.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | /** 25 | * Junit Assert wrapper methods class 26 | */ 27 | public class KryoAssert { 28 | 29 | private KryoAssert() { 30 | 31 | } 32 | 33 | public static void assertDoubleEquals(double expected, double actual) { 34 | assertEquals(expected, actual, 0.0); 35 | } 36 | 37 | public static void assertFloatEquals(float expected, double actual) { 38 | assertEquals(expected, actual, 0.0); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/RegistrationTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.io.Input; 25 | import com.esotericsoftware.kryo.io.Output; 26 | import com.esotericsoftware.kryo.serializers.DefaultSerializers.LongSerializer; 27 | import com.esotericsoftware.kryo.serializers.FieldSerializer; 28 | 29 | import java.io.IOException; 30 | 31 | import org.junit.jupiter.api.Test; 32 | 33 | class RegistrationTest { 34 | @Test 35 | void testDefaultSerializerOrder () { 36 | Kryo kryo = new Kryo(); 37 | kryo.addDefaultSerializer(Fruit.class, new FieldSerializer(kryo, Fruit.class)); 38 | FieldSerializer appleSerializer = new FieldSerializer(kryo, Apple.class); 39 | kryo.addDefaultSerializer(Apple.class, appleSerializer); 40 | assertSame(appleSerializer, kryo.getDefaultSerializer(Apple.class)); 41 | } 42 | 43 | @Test 44 | void testReplaceRegistration () throws IOException { 45 | Kryo kryo = new Kryo(); 46 | kryo.register(double[].class, 7); // Replace long with double[]. 47 | kryo.register(Some.class); 48 | kryo.register(long.class, new LongSerializer()); 49 | 50 | { 51 | Some s = new Some(2); 52 | Output output = new Output(1024); 53 | kryo.writeObject(output, s); 54 | output.flush(); 55 | 56 | Input input = new Input(output.getBuffer()); 57 | Some r = kryo.readObject(input, Some.class); // OK! 58 | assertEquals(r.value, 2); 59 | } 60 | 61 | { 62 | Some s = new Some(2L); 63 | Output output = new Output(1024); 64 | kryo.writeObject(output, s); 65 | output.flush(); 66 | 67 | Input input = new Input(output.getBuffer()); 68 | Some r = kryo.readObject(input, Some.class); 69 | assertEquals(r.value, 2L); 70 | } 71 | } 72 | 73 | public static class Some { 74 | public T value; 75 | 76 | public Some () { 77 | } 78 | 79 | public Some (T t) { 80 | this.value = t; 81 | } 82 | } 83 | 84 | public static class Fruit { 85 | } 86 | 87 | public static class Apple extends Fruit { 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/Unsafe.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo; 21 | 22 | import java.lang.annotation.ElementType; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | import org.junit.jupiter.api.condition.EnabledIf; 28 | 29 | /** Conditional annotation that runs a test only if Unsafe is available */ 30 | @Target(value = {ElementType.METHOD, ElementType.TYPE}) 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @EnabledIf("com.esotericsoftware.kryo.util.Util#isUnsafeAvailable") 33 | public @interface Unsafe { 34 | } 35 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/io/ChunkedTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.io; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.KryoException; 25 | import org.junit.jupiter.api.Test; 26 | 27 | /** @author Nathan Sweet */ 28 | class ChunkedTest { 29 | @Test 30 | void testChunks () { 31 | Output output = new Output(512); 32 | output.writeInt(1234); 33 | OutputChunked outputChunked = new OutputChunked(output); 34 | outputChunked.writeInt(1); 35 | outputChunked.endChunk(); 36 | outputChunked.writeInt(2); 37 | outputChunked.endChunk(); 38 | outputChunked.writeInt(3); 39 | outputChunked.endChunk(); 40 | outputChunked.writeInt(4); 41 | outputChunked.endChunk(); 42 | outputChunked.writeInt(5); 43 | outputChunked.endChunk(); 44 | output.writeInt(5678); 45 | output.close(); 46 | 47 | Input input = new Input(output.getBuffer()); 48 | assertEquals(1234, input.readInt()); 49 | InputChunked inputChunked = new InputChunked(input); 50 | assertEquals(1, inputChunked.readInt()); 51 | inputChunked.nextChunk(); 52 | inputChunked.nextChunk(); // skip 3 53 | assertEquals(3, inputChunked.readInt()); 54 | inputChunked.nextChunk(); 55 | inputChunked.nextChunk(); // skip 4 56 | assertEquals(5, inputChunked.readInt()); 57 | assertEquals(5678, input.readInt()); 58 | input.close(); 59 | } 60 | 61 | @Test 62 | void testSkipAfterUnderFlow () { 63 | Output output = new Output(512); 64 | OutputChunked outputChunked = new OutputChunked(output); 65 | outputChunked.writeInt(1); 66 | outputChunked.endChunk(); 67 | outputChunked.writeInt(2); 68 | outputChunked.endChunk(); 69 | output.close(); 70 | 71 | Input input = new Input(output.getBuffer()); 72 | InputChunked inputChunked = new InputChunked(input); 73 | assertEquals(1, inputChunked.readInt()); 74 | // trigger buffer underflow 75 | assertThrows(KryoException.class, inputChunked::readInt); 76 | inputChunked.nextChunk(); 77 | assertEquals(2, inputChunked.readInt()); 78 | input.close(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/ArraySerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.KryoTestCase; 25 | import com.esotericsoftware.kryo.serializers.DefaultArraySerializers.ObjectArraySerializer; 26 | 27 | import org.junit.jupiter.api.Test; 28 | 29 | /** @author Nathan Sweet */ 30 | class ArraySerializerTest extends KryoTestCase { 31 | { 32 | supportsCopy = true; 33 | } 34 | 35 | @Test 36 | void testArrays () { 37 | kryo.register(int[].class); 38 | kryo.register(int[][].class); 39 | kryo.register(int[][][].class); 40 | kryo.register(String[].class); 41 | kryo.register(Object[].class); 42 | roundTrip(4, new Object[] {null, null}); 43 | roundTrip(6, new Object[] {null, "2"}); 44 | roundTrip(6, new int[] {1, 2, 3, 4}); 45 | roundTrip(7, new int[] {1, 2, -100, 4}); 46 | roundTrip(9, new int[] {1, 2, -100, 40000}); 47 | roundTrip(9, new int[][] {{1, 2}, {100, 4}}); 48 | roundTrip(11, new int[][] {{1}, {2}, {100}, {4}}); 49 | roundTrip(13, new int[][][] {{{1}, {2}}, {{100}, {4}}}); 50 | roundTrip(12, new String[] {"11", "2222", "3", "4"}); 51 | roundTrip(11, new String[] {"11", "2222", null, "4"}); 52 | roundTrip(28, 53 | new Object[] {new String[] {"11", "2222", null, "4"}, new int[] {1, 2, 3, 4}, new int[][] {{1, 2}, {100, 4}}}); 54 | 55 | ObjectArraySerializer serializer = new ObjectArraySerializer(kryo, String[].class); 56 | kryo.register(String[].class, serializer); 57 | serializer.setElementsAreSameType(true); 58 | roundTrip(11, new String[] {"11", "2222", null, "4"}); 59 | serializer.setElementsAreSameType(false); 60 | roundTrip(11, new String[] {"11", "2222", null, "4"}); 61 | roundTrip(5, new String[] {null, null, null}); 62 | roundTrip(2, new String[] {}); 63 | serializer.setElementsAreSameType(true); 64 | roundTrip(12, new String[] {"11", "2222", "3", "4"}); 65 | serializer.setElementsCanBeNull(false); 66 | roundTrip(12, new String[] {"11", "2222", "3", "4"}); 67 | 68 | serializer = new ObjectArraySerializer(kryo, Float[].class); 69 | kryo.register(Float[][].class, serializer); 70 | kryo.register(Float[].class, serializer); 71 | Float[][] array = new Float[4][]; 72 | array[0] = new Float[] {0.0f, 1.0f}; 73 | array[1] = null; 74 | array[2] = new Float[] {2.0f, 3.0f}; 75 | array[3] = new Float[] {3.0f}; 76 | roundTrip(31, array); 77 | } 78 | 79 | @Test 80 | void testRecursiveArray () { 81 | Object[] array = new Object[1]; 82 | array[0] = array; 83 | kryo.register(Object[].class); 84 | Object[] copy = kryo.copy(array); 85 | assertTrue(copy == copy[0]); 86 | } 87 | 88 | @Test 89 | void testStringArray () { 90 | String moo = "moooooooooooooooooo"; 91 | String[] array = {moo, "dog", moo}; 92 | kryo.register(String[].class); 93 | roundTrip(43, array); 94 | 95 | kryo.setReferences(true); 96 | roundTrip(28, array); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/BeanSerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | /** @author Nathan Sweet */ 27 | class BeanSerializerTest extends KryoTestCase { 28 | { 29 | supportsCopy = true; 30 | } 31 | 32 | @Test 33 | void testBeanSerializer () { 34 | kryo.register(TestClass.class, new BeanSerializer(kryo, TestClass.class)); 35 | 36 | TestClass test = new TestClass(); 37 | test.setOptional(12); 38 | test.setNullField("value"); 39 | test.setText("123"); 40 | test.setChild(new TestClass()); 41 | roundTrip(37, test); 42 | test.setNullField(null); 43 | roundTrip(33, test); 44 | } 45 | 46 | public static class TestClass { 47 | private String text = "something"; 48 | private String nullField; 49 | private TestClass child; 50 | private TestClass child2; 51 | private float abc = 1.2f; 52 | private int optional; 53 | 54 | public String getText () { 55 | return text; 56 | } 57 | 58 | public void setText (String text) { 59 | this.text = text; 60 | } 61 | 62 | public String getNullField () { 63 | return nullField; 64 | } 65 | 66 | public void setNullField (String nullField) { 67 | this.nullField = nullField; 68 | } 69 | 70 | public TestClass getChild () { 71 | return child; 72 | } 73 | 74 | public void setChild (TestClass child) { 75 | this.child = child; 76 | } 77 | 78 | public TestClass getChild2 () { 79 | return child2; 80 | } 81 | 82 | public void setChild2 (TestClass child2) { 83 | this.child2 = child2; 84 | } 85 | 86 | public float getAbc () { 87 | return abc; 88 | } 89 | 90 | public void setAbc (float abc) { 91 | this.abc = abc; 92 | } 93 | 94 | public int getOptional () { 95 | return optional; 96 | } 97 | 98 | public void setOptional (int optional) { 99 | this.optional = optional; 100 | } 101 | 102 | public boolean equals (Object obj) { 103 | if (this == obj) return true; 104 | if (obj == null) return false; 105 | if (getClass() != obj.getClass()) return false; 106 | TestClass other = (TestClass)obj; 107 | if (Float.floatToIntBits(abc) != Float.floatToIntBits(other.abc)) return false; 108 | if (child == null) { 109 | if (other.child != null) return false; 110 | } else if (child != this && !child.equals(other.child)) return false; 111 | if (child2 == null) { 112 | if (other.child2 != null) return false; 113 | } else if (child2 != this && !child2.equals(other.child2)) return false; 114 | if (nullField == null) { 115 | if (other.nullField != null) return false; 116 | } else if (!nullField.equals(other.nullField)) return false; 117 | if (text == null) { 118 | if (other.text != null) return false; 119 | } else if (!text.equals(other.text)) return false; 120 | return true; 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/BlowfishSerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | import com.esotericsoftware.kryo.serializers.DefaultSerializers.StringSerializer; 24 | 25 | import javax.crypto.KeyGenerator; 26 | 27 | import org.junit.jupiter.api.Test; 28 | 29 | /** @author Nathan Sweet */ 30 | class BlowfishSerializerTest extends KryoTestCase { 31 | @Test 32 | void testZip () throws Exception { 33 | byte[] key = KeyGenerator.getInstance("Blowfish").generateKey().getEncoded(); 34 | kryo.register(String.class, new BlowfishSerializer(new StringSerializer(), key)); 35 | roundTrip(49, "abcdefabcdefabcdefabcdefabcdefabcdefabcdef"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/DeflateSerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | import com.esotericsoftware.kryo.serializers.DefaultSerializers.StringSerializer; 24 | 25 | import org.junit.jupiter.api.Test; 26 | 27 | /** @author Nathan Sweet */ 28 | class DeflateSerializerTest extends KryoTestCase { 29 | @Test 30 | void testString () { 31 | kryo.register(String.class, new DeflateSerializer(new StringSerializer())); 32 | roundTrip(14, "abcdefabcdefabcdefabcdefabcdefabcdefabcdef"); 33 | } 34 | 35 | @Test 36 | void testGraph () { 37 | kryo.register(Message.class); 38 | kryo.register(MessageType.class); 39 | kryo.register(ServerPhysicsUpdate.class, new DeflateSerializer(kryo.getDefaultSerializer(ServerPhysicsUpdate.class))); 40 | 41 | ServerPhysicsUpdate physicsUpdate = new ServerPhysicsUpdate(); 42 | physicsUpdate.value = 1; 43 | Message message = new Message(); 44 | message.type = MessageType.SERVER_UPDATE; 45 | message.data = physicsUpdate; 46 | 47 | roundTrip(8, message); 48 | } 49 | 50 | public static class ServerPhysicsUpdate { 51 | public int value; 52 | 53 | public ServerPhysicsUpdate () { 54 | } 55 | 56 | public int hashCode () { 57 | final int prime = 31; 58 | int result = 1; 59 | result = prime * result + value; 60 | return result; 61 | } 62 | 63 | public boolean equals (Object obj) { 64 | if (this == obj) return true; 65 | if (obj == null) return false; 66 | if (getClass() != obj.getClass()) return false; 67 | ServerPhysicsUpdate other = (ServerPhysicsUpdate)obj; 68 | if (value != other.value) return false; 69 | return true; 70 | } 71 | } 72 | 73 | public static enum MessageType { 74 | SERVER_UPDATE 75 | } 76 | 77 | public static class Message { 78 | public MessageType type; 79 | public Object data; 80 | 81 | public Message () { 82 | } 83 | 84 | public int hashCode () { 85 | final int prime = 31; 86 | int result = 1; 87 | result = prime * result + (data == null ? 0 : data.hashCode()); 88 | result = prime * result + (type == null ? 0 : type.hashCode()); 89 | return result; 90 | } 91 | 92 | public boolean equals (Object obj) { 93 | if (this == obj) return true; 94 | if (obj == null) return false; 95 | if (getClass() != obj.getClass()) return false; 96 | Message other = (Message)obj; 97 | if (data == null) { 98 | if (other.data != null) return false; 99 | } else if (!data.equals(other.data)) return false; 100 | if (type != other.type) return false; 101 | return true; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/EnumNameSerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.Kryo; 25 | import com.esotericsoftware.kryo.KryoTestCase; 26 | import com.esotericsoftware.kryo.io.Input; 27 | import com.esotericsoftware.kryo.io.Output; 28 | 29 | import java.util.EnumSet; 30 | 31 | import org.junit.jupiter.api.Test; 32 | 33 | /** @author KwonNam Son */ 34 | class EnumNameSerializerTest extends KryoTestCase { 35 | @Test 36 | void testEnumNameSerializer () { 37 | kryo.addDefaultSerializer(Enum.class, EnumNameSerializer.class); 38 | kryo.register(TestNameEnum.class); 39 | kryo.register(TestAnotherNameEnum.class); 40 | 41 | // 1 byte for identifying class name, 42 | // rest bytes for enum's name 43 | roundTrip(6, TestNameEnum.HELLO); 44 | roundTrip(5, TestNameEnum.KRYO); 45 | 46 | roundTrip(7, TestAnotherNameEnum.SUNDAY); 47 | roundTrip(8, TestAnotherNameEnum.TUESDAY); 48 | 49 | kryo = new Kryo(); 50 | kryo.addDefaultSerializer(Enum.class, EnumNameSerializer.class); 51 | kryo.setRegistrationRequired(false); 52 | 53 | roundTrip(80, TestNameEnum.WORLD); 54 | roundTrip(88, TestAnotherNameEnum.MONDAY); 55 | } 56 | 57 | @Test 58 | void testEnumSetSerializerWithEnumNameSerializer () { 59 | kryo.addDefaultSerializer(Enum.class, EnumNameSerializer.class); 60 | kryo.register(EnumSet.class); 61 | kryo.register(TestNameEnum.class); 62 | 63 | // roundTrip for EnumSet with EnumNameSerializer does not work. 64 | 65 | // test directly 66 | Output output = new Output(1024); 67 | kryo.writeClassAndObject(output, EnumSet.of(TestNameEnum.HELLO, TestNameEnum.WORLD)); 68 | byte[] bytes = output.toBytes(); 69 | 70 | EnumSet enumSet = (EnumSet)kryo.readClassAndObject(new Input(bytes)); 71 | assertEquals(enumSet.size(), 2); 72 | assertTrue(enumSet.contains(TestNameEnum.HELLO)); 73 | assertTrue(enumSet.contains(TestNameEnum.WORLD)); 74 | assertFalse(enumSet.contains(TestNameEnum.KRYO)); 75 | 76 | // empty EnumSet 77 | roundTrip(3, EnumSet.noneOf(TestNameEnum.class)); 78 | } 79 | 80 | @Test 81 | void testEnumNameSerializerWithMethods () { 82 | kryo.addDefaultSerializer(Enum.class, EnumNameSerializer.class); 83 | 84 | kryo.register(TestNameEnumWithMethods.class); 85 | roundTrip(6, TestNameEnumWithMethods.ALPHA); 86 | roundTrip(5, TestNameEnumWithMethods.BETA); 87 | 88 | kryo = new Kryo(); 89 | kryo.addDefaultSerializer(Enum.class, EnumNameSerializer.class); 90 | kryo.setRegistrationRequired(false); 91 | 92 | roundTrip(93, TestNameEnumWithMethods.ALPHA); 93 | roundTrip(92, TestNameEnumWithMethods.BETA); 94 | } 95 | 96 | public enum TestNameEnum { 97 | HELLO, KRYO, WORLD 98 | } 99 | 100 | public enum TestAnotherNameEnum { 101 | SUNDAY, MONDAY, TUESDAY 102 | } 103 | 104 | public enum TestNameEnumWithMethods { 105 | ALPHA { 106 | }, 107 | BETA { 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/JavaSerializerTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | 24 | import java.io.Serializable; 25 | import java.net.URL; 26 | import java.net.URLClassLoader; 27 | 28 | import org.junit.jupiter.api.Test; 29 | 30 | /** @author Nathan Sweet */ 31 | class JavaSerializerTest extends KryoTestCase { 32 | @Test 33 | void testJavaSerializer () { 34 | kryo.register(String.class, new JavaSerializer()); 35 | roundTrip(50, "abcdefabcdefabcdefabcdefabcdefabcdefabcdef"); 36 | roundTrip(12, "meow"); 37 | 38 | kryo.register(TestClass.class, new JavaSerializer()); 39 | TestClass test = new TestClass(); 40 | test.stringField = "fubar"; 41 | test.intField = 54321; 42 | roundTrip(146, test); 43 | roundTrip(146, test); 44 | roundTrip(146, test); 45 | } 46 | 47 | @Test 48 | void testJavaSerializerFallbackToDefaultClassLoader () { 49 | kryo.setClassLoader(new URLClassLoader(new URL[]{}, null)); 50 | 51 | kryo.register(TestClass.class, new JavaSerializer()); 52 | 53 | TestClass test = new TestClass(); 54 | test.intField = 54321; 55 | roundTrip(139, test); 56 | } 57 | 58 | public static class TestClass implements Serializable { 59 | String stringField; 60 | int intField; 61 | 62 | public boolean equals (Object obj) { 63 | if (this == obj) return true; 64 | if (obj == null) return false; 65 | if (getClass() != obj.getClass()) return false; 66 | TestClass other = (TestClass)obj; 67 | if (intField != other.intField) return false; 68 | if (stringField == null) { 69 | if (other.stringField != null) return false; 70 | } else if (!stringField.equals(other.stringField)) return false; 71 | return true; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/serializers/OptionalSerializersTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.serializers; 21 | 22 | import com.esotericsoftware.kryo.KryoTestCase; 23 | 24 | import java.util.Objects; 25 | import java.util.Optional; 26 | import java.util.OptionalDouble; 27 | import java.util.OptionalInt; 28 | import java.util.OptionalLong; 29 | 30 | import org.junit.jupiter.api.BeforeEach; 31 | import org.junit.jupiter.api.Test; 32 | 33 | /** Test for java 8 Optional* serializers. */ 34 | class OptionalSerializersTest extends KryoTestCase { 35 | 36 | { 37 | supportsCopy = true; 38 | } 39 | 40 | @BeforeEach 41 | public void setUp () throws Exception { 42 | super.setUp(); 43 | kryo.register(Optional.class); 44 | kryo.register(OptionalInt.class); 45 | kryo.register(OptionalLong.class); 46 | kryo.register(OptionalDouble.class); 47 | kryo.register(TestClass.class); 48 | } 49 | 50 | @Test 51 | void testOptional () { 52 | roundTrip(2, new TestClass(null)); 53 | roundTrip(3, new TestClass(Optional. empty())); 54 | roundTrip(6, new TestClass(Optional.of("foo"))); 55 | } 56 | 57 | @Test 58 | void testOptionalInt () { 59 | roundTrip(2, OptionalInt.empty()); 60 | roundTrip(6, OptionalInt.of(Integer.MIN_VALUE)); 61 | roundTrip(6, OptionalInt.of(Integer.MAX_VALUE)); 62 | } 63 | 64 | @Test 65 | void testOptionalLong () { 66 | roundTrip(2, OptionalLong.empty()); 67 | roundTrip(10, OptionalLong.of(Long.MIN_VALUE)); 68 | roundTrip(10, OptionalLong.of(Long.MAX_VALUE)); 69 | } 70 | 71 | @Test 72 | void testOptionalDouble () { 73 | roundTrip(2, OptionalDouble.empty()); 74 | roundTrip(10, OptionalDouble.of(Double.MIN_VALUE)); 75 | roundTrip(10, OptionalDouble.of(Double.MAX_VALUE)); 76 | } 77 | 78 | public static class TestClass { 79 | Optional maybe; 80 | 81 | public TestClass () { 82 | } 83 | 84 | public TestClass (Optional maybe) { 85 | this.maybe = maybe; 86 | } 87 | 88 | public boolean equals (Object o) { 89 | if (this == o) return true; 90 | if (o == null || getClass() != o.getClass()) return false; 91 | TestClass testClass = (TestClass)o; 92 | return Objects.equals(maybe, testClass.maybe); 93 | 94 | } 95 | 96 | public int hashCode () { 97 | return Objects.hashCode(maybe); 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/util/PoolTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import com.esotericsoftware.kryo.Kryo; 25 | import com.esotericsoftware.kryo.KryoTestCase; 26 | 27 | import java.util.Arrays; 28 | import java.util.Collection; 29 | import java.util.List; 30 | import java.util.stream.Collectors; 31 | import java.util.stream.IntStream; 32 | 33 | import org.junit.jupiter.params.ParameterizedTest; 34 | import org.junit.jupiter.params.provider.MethodSource; 35 | 36 | class PoolTest extends KryoTestCase { 37 | 38 | private static final int MAXIMUM_CAPACITY = 4; 39 | 40 | public static Collection data () { 41 | return Arrays.asList(new Object[][] { 42 | {new TestPool(false, false, MAXIMUM_CAPACITY)}, 43 | {new TestPool(true, false, MAXIMUM_CAPACITY)}, 44 | {new TestPool(false, true, MAXIMUM_CAPACITY)}, 45 | {new TestPool(true, true, MAXIMUM_CAPACITY)}}); 46 | } 47 | 48 | @ParameterizedTest 49 | @MethodSource("data") 50 | void obtainShouldReturnAvailableInstance (Pool pool) { 51 | Kryo kryo = pool.obtain(); 52 | pool.free(kryo); 53 | assertSame(kryo, pool.obtain()); 54 | } 55 | 56 | @ParameterizedTest 57 | @MethodSource("data") 58 | void freeShouldAddKryoToPool (Pool pool) { 59 | assertEquals(0, pool.getFree()); 60 | Kryo kryo = pool.obtain(); 61 | pool.free(kryo); 62 | assertEquals(1, pool.getFree()); 63 | } 64 | 65 | @ParameterizedTest 66 | @MethodSource("data") 67 | void freeShouldNotAddMoreThanMaximumCapacityToKryoPool (Pool pool) { 68 | final List kryos = IntStream.rangeClosed(0, MAXIMUM_CAPACITY + 1) 69 | .mapToObj(i -> pool.obtain()) 70 | .collect(Collectors.toList()); 71 | for (Kryo kryo : kryos) { 72 | pool.free(kryo); 73 | } 74 | assertEquals(MAXIMUM_CAPACITY, pool.getFree()); 75 | } 76 | 77 | @ParameterizedTest 78 | @MethodSource("data") 79 | void testSize (Pool pool) { 80 | assertEquals(0, pool.getFree()); 81 | Kryo kryo1 = pool.obtain(); 82 | assertEquals(0, pool.getFree()); 83 | Kryo kryo2 = pool.obtain(); 84 | assertNotSame(kryo1, kryo2); 85 | pool.free(kryo1); 86 | assertEquals(1, pool.getFree()); 87 | pool.free(kryo2); 88 | assertEquals(2, pool.getFree()); 89 | } 90 | 91 | private static class TestPool extends Pool { 92 | 93 | private final boolean threadSafe; 94 | private final boolean softReferences; 95 | private final int maximumCapacity; 96 | 97 | public TestPool (boolean threadSafe, boolean softReferences, int maximumCapacity) { 98 | super(threadSafe, softReferences, maximumCapacity); 99 | this.threadSafe = threadSafe; 100 | this.softReferences = softReferences; 101 | this.maximumCapacity = maximumCapacity; 102 | } 103 | 104 | @Override 105 | protected Kryo create () { 106 | return new Kryo(); 107 | } 108 | 109 | public String toString() { 110 | return "TestPool{" + 111 | "threadSafe=" + threadSafe + 112 | ", softReferences=" + softReferences + 113 | ", maximumCapacity=" + maximumCapacity + 114 | '}'; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /test/com/esotericsoftware/kryo/util/UtilTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2008-2025, Nathan Sweet 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following 5 | * conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 9 | * disclaimer in the documentation and/or other materials provided with the distribution. 10 | * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived 11 | * from this software without specific prior written permission. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 14 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 15 | * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 17 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 19 | 20 | package com.esotericsoftware.kryo.util; 21 | 22 | import static org.junit.jupiter.api.Assertions.*; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | import java.io.Serializable; 27 | 28 | class UtilTest { 29 | 30 | @Test 31 | void testIsAssignableTo() { 32 | assertTrue(Util.isAssignableTo(Long.class, long.class)); 33 | assertTrue(Util.isAssignableTo(long.class, Long.class)); 34 | assertTrue(Util.isAssignableTo(Long.class, Long.class)); 35 | assertTrue(Util.isAssignableTo(long.class, long.class)); 36 | assertTrue(Util.isAssignableTo(Long.class, Object.class)); 37 | assertTrue(Util.isAssignableTo(long.class, Object.class)); 38 | assertTrue(Util.isAssignableTo(Integer.class, Comparable.class)); 39 | assertTrue(Util.isAssignableTo(Integer.class, Serializable.class)); 40 | assertTrue(Util.isAssignableTo(int.class, Comparable.class)); 41 | assertTrue(Util.isAssignableTo(int.class, Serializable.class)); 42 | 43 | assertFalse(Util.isAssignableTo(String.class, Long.class)); 44 | assertFalse(Util.isAssignableTo(String.class, long.class)); 45 | } 46 | 47 | @Test 48 | void testGetArrayType() { 49 | assertEquals(int[].class, Util.getArrayType(int.class)); 50 | assertEquals(Integer[].class, Util.getArrayType(Integer.class)); 51 | assertEquals(String[].class, Util.getArrayType(String.class)); 52 | assertEquals(String[][].class, Util.getArrayType(String[].class)); 53 | assertEquals(Object[].class, Util.getArrayType(Object.class)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/resources/TestData-bytebuffer.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestData-bytebuffer.ser -------------------------------------------------------------------------------- /test/resources/TestData-standard.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestData-standard.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava11-bytebuffer.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava11-bytebuffer.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava11-standard.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava11-standard.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava17-bytebuffer.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava17-bytebuffer.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava17-standard.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava17-standard.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava8-bytebuffer.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava8-bytebuffer.ser -------------------------------------------------------------------------------- /test/resources/TestDataJava8-standard.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/kryo/23fbc2d531b9d7fe2408ad825fbc9f27b42f5936/test/resources/TestDataJava8-standard.ser --------------------------------------------------------------------------------