Merge pull request #4 from dubbogo/master

pull code
diff --git a/.travis.yml b/.travis.yml
index 801cec3..db25d8d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,5 +8,5 @@
   - mvn clean package -f test_hessian/pom.xml
   - mvn clean package -f test_dubbo/pom.xml
   - go fmt && [[ -z `git status -s` ]]
-  - GO111MODULE=on && go mod vendor && go test -race && go test -bench . -race
+  - GO111MODULE=on && go mod vendor && go test -race -v && go test -bench . -race
 
diff --git a/README.md b/README.md
index 165a483..67157ac 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,16 @@
 
 ---
 
-It's a golang hessian library used by dubbogo.
+It's a golang hessian library used by [Apache/dubbo-go](github.com/apache/dubbo-go).
+
+## Feature List
+
+* [All JDK Exceptions](https://github.com/dubbogo/hessian2/issues/59)
+* [Function Alias By Alias](https://github.com/dubbogo/hessian2/issues/19)
+* [Java Bigdecimal](https://github.com/dubbogo/hessian2/issues/89)
+* [Java Date & Time](https://github.com/dubbogo/hessian2/issues/90)
+* [Java Generic Invokation](https://github.com/dubbogo/hessian2/issues/84)
+* [Dubbo Attachements](https://github.com/dubbogo/hessian2/issues/49)
 
 ## Basic Usage Examples
 
diff --git a/codec.go b/codec.go
index 51b21b8..6c91ce5 100644
--- a/codec.go
+++ b/codec.go
@@ -276,7 +276,7 @@
 		return v
 	}
 	if v, ok := in.(*_refHolder); ok {
-		in = v.value
+		return v.value
 	}
 	return reflect.ValueOf(in)
 }
diff --git a/const.go b/const.go
index 53a056f..d4ba923 100644
--- a/const.go
+++ b/const.go
@@ -142,6 +142,7 @@
 	ARRAY_LONG       = "[long"
 
 	PATH_KEY      = "path"
+	GROUP_KEY     = "group"
 	INTERFACE_KEY = "interface"
 	VERSION_KEY   = "version"
 	TIMEOUT_KEY   = "timeout"
diff --git a/decode.go b/decode.go
index 4e3d07a..a314f76 100644
--- a/decode.go
+++ b/decode.go
@@ -27,8 +27,11 @@
 
 // Decoder struct
 type Decoder struct {
-	reader        *bufio.Reader
-	refs          []interface{}
+	reader *bufio.Reader
+	refs   []interface{}
+	// record type refs, both list and map need it
+	// todo: map
+	typeRefs      *TypeRefs
 	classInfoList []classInfo
 }
 
@@ -40,7 +43,7 @@
 
 // NewDecoder generate a decoder instance
 func NewDecoder(b []byte) *Decoder {
-	return &Decoder{reader: bufio.NewReader(bytes.NewReader(b))}
+	return &Decoder{reader: bufio.NewReader(bytes.NewReader(b)), typeRefs: &TypeRefs{records: map[string]bool{}}}
 }
 
 /////////////////////////////////////////
@@ -210,3 +213,24 @@
 		return nil, perrors.Errorf("Invalid type: %v,>>%v<<<", string(tag), d.peek(d.len()))
 	}
 }
+
+/////////////////////////////////////////
+// typeRefs
+/////////////////////////////////////////
+type TypeRefs struct {
+	typeRefs []reflect.Type
+	records  map[string]bool // record if existing for type
+}
+
+// appendTypeRefs add list or map type ref
+func (t *TypeRefs) appendTypeRefs(name string, p reflect.Type) {
+	if t.records[name] {
+		return
+	}
+	t.records[name] = true
+	t.typeRefs = append(t.typeRefs, p)
+}
+
+func (t *TypeRefs) Get(index int) reflect.Type {
+	return t.typeRefs[index]
+}
diff --git a/decode_test.go b/decode_test.go
index 8dae2b6..e877b52 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -57,6 +57,7 @@
 
 func getJavaReply(method, className string) []byte {
 	genHessianJar()
+	log.Println("get java reply: ", className, method)
 	cmdArgs := []string{"-jar", hessianJar, method}
 	if className != "" {
 		cmdArgs = append(cmdArgs, className)
diff --git a/encode.go b/encode.go
index 30d6364..f5f333b 100644
--- a/encode.go
+++ b/encode.go
@@ -92,6 +92,8 @@
 		// use int64 type to handle int, to avoid  panic like :  reflect: Call using int32 as type int64 [recovered]
 		// when decode
 		e.buffer = encInt64(e.buffer, int64(val))
+	case uint:
+		e.buffer = encInt64(e.buffer, int64(val))
 
 	case int64:
 		e.buffer = encInt64(e.buffer, val)
@@ -122,12 +124,21 @@
 		switch t.Kind() {
 		case reflect.Struct:
 			if p, ok := v.(POJO); ok {
+				var clazz string
+				vv := reflect.ValueOf(v)
+				vv = UnpackPtr(vv)
+				if vv.IsValid() {
+					clazz = p.JavaClassName()
+					if c, ok := GetSerializer(clazz); ok {
+						return c.EncObject(e, p)
+					}
+				}
 				return e.encObject(p)
 			}
 
 			return perrors.Errorf("struct type not Support! %s[%v] is not a instance of POJO!", t.String(), v)
 		case reflect.Slice, reflect.Array:
-			return e.encUntypedList(v)
+			return e.encList(v)
 		case reflect.Map: // the type must be map[string]int
 			return e.encMap(v)
 		default:
diff --git a/go.mod b/go.mod
index 971dd66..24e71dd 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,7 @@
 
 require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/dubbogo/gost v1.1.1
 	github.com/pkg/errors v0.8.1
 	github.com/stretchr/testify v1.3.0
 )
diff --git a/go.sum b/go.sum
index b0ebc7a..dd2e8c8 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,10 @@
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dubbogo/gost v1.0.1-0.20190709080436-ae4ac3e96ad1 h1:RrdI0SvwHR2DKNLJj+heaIbeb9qYig9QlniddKB6ViU=
+github.com/dubbogo/gost v1.0.1-0.20190709080436-ae4ac3e96ad1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
+github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
+github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
diff --git a/hessian.go b/hessian.go
index 171191a..1811c55 100644
--- a/hessian.go
+++ b/hessian.go
@@ -51,8 +51,8 @@
 type Service struct {
 	Path      string
 	Interface string
+	Group     string
 	Version   string
-	Target    string // Service Name
 	Method    string
 	Timeout   time.Duration // request timeout
 }
diff --git a/hessian_test.go b/hessian_test.go
index 45b4768..a372a77 100644
--- a/hessian_test.go
+++ b/hessian_test.go
@@ -39,10 +39,9 @@
 	RegisterPOJO(&Case{})
 	codecW := NewHessianCodec(nil)
 	resp, err := codecW.Write(Service{
-		Path:      "/test",
+		Path:      "test",
 		Interface: "ITest",
 		Version:   "v1.0",
-		Target:    "test",
 		Method:    "test",
 		Timeout:   time.Second * 10,
 	}, DubboHeader{
@@ -129,9 +128,9 @@
 			assert.FailNow(t, "no key in decoded response map")
 		}
 
-		mapValueArr, ok := c.([]interface{})
+		mapValueArr, ok := c.([]*Case)
 		if !ok {
-			assert.FailNow(t, "invalid decoded response map value", "expect []interface{}, but get %v", reflect.TypeOf(c))
+			assert.FailNow(t, "invalid decoded response map value", "expect []*Case, but get %v", reflect.TypeOf(c))
 		}
 		assert.Equal(t, 1, len(mapValueArr))
 		assert.Equal(t, &caseObj, mapValueArr[0])
diff --git a/java_exception.go b/java_exception.go
index 58ca2a6..010a6dc 100644
--- a/java_exception.go
+++ b/java_exception.go
@@ -16,15 +16,6 @@
 
 import "github.com/dubbogo/hessian2/java_exception"
 
-////////////////////////////
-// Throwable interface
-////////////////////////////
-
-type Throwabler interface {
-	Error() string
-	JavaClassName() string
-}
-
 func init() {
 	RegisterPOJO(&java_exception.Class{})
 	RegisterPOJO(&java_exception.Throwable{})
@@ -37,6 +28,11 @@
 	RegisterPOJO(&java_exception.IllegalStateException{})
 	RegisterPOJO(&java_exception.IllegalMonitorStateException{})
 	RegisterPOJO(&java_exception.EnumConstantNotPresentException{})
+	RegisterPOJO(&java_exception.CloneNotSupportedException{})
+	RegisterPOJO(&java_exception.InterruptedException{})
+	RegisterPOJO(&java_exception.InterruptedIOException{})
+	RegisterPOJO(&java_exception.LambdaConversionException{})
+	RegisterPOJO(&java_exception.UnmodifiableClassException{})
 	RegisterPOJO(&java_exception.MalformedParameterizedTypeException{})
 	RegisterPOJO(&java_exception.MalformedParametersException{})
 	RegisterPOJO(&java_exception.TypeNotPresentException{})
@@ -73,4 +69,39 @@
 	RegisterPOJO(&java_exception.EmptyStackException{})
 	RegisterPOJO(&java_exception.IllformedLocaleException{})
 	RegisterPOJO(&java_exception.NoSuchElementException{})
+	RegisterPOJO(&java_exception.NegativeArraySizeException{})
+	RegisterPOJO(&java_exception.UnsupportedOperationException{})
+	RegisterPOJO(&java_exception.ArithmeticException{})
+	RegisterPOJO(&java_exception.InputMismatchException{})
+	RegisterPOJO(&java_exception.ExecutionException{})
+	RegisterPOJO(&java_exception.InvalidPreferencesFormatException{})
+	RegisterPOJO(&java_exception.TimeoutException{})
+	RegisterPOJO(&java_exception.BackingStoreException{})
+	RegisterPOJO(&java_exception.DataFormatException{})
+	RegisterPOJO(&java_exception.BrokenBarrierException{})
+	RegisterPOJO(&java_exception.TooManyListenersException{})
+	RegisterPOJO(&java_exception.InvalidPropertiesFormatException{})
+	RegisterPOJO(&java_exception.ZipException{})
+	RegisterPOJO(&java_exception.JarException{})
+	RegisterPOJO(&java_exception.IllegalClassFormatException{})
+	RegisterPOJO(&java_exception.ReflectiveOperationException{})
+	RegisterPOJO(&java_exception.InvocationTargetException{})
+	RegisterPOJO(&java_exception.NoSuchMethodException{})
+	RegisterPOJO(&java_exception.NoSuchFieldException{})
+	RegisterPOJO(&java_exception.IllegalAccessException{})
+	RegisterPOJO(&java_exception.ClassNotFoundException{})
+	RegisterPOJO(&java_exception.InstantiationException{})
+	RegisterPOJO(&java_exception.DateTimeException{})
+	RegisterPOJO(&java_exception.UnsupportedTemporalTypeException{})
+	RegisterPOJO(&java_exception.ZoneRulesException{})
+	RegisterPOJO(&java_exception.DateTimeParseException{})
+	RegisterPOJO(&java_exception.FormatterClosedException{})
+	RegisterPOJO(&java_exception.CancellationException{})
+	RegisterPOJO(&java_exception.UnknownFormatConversionException{})
+	RegisterPOJO(&java_exception.UnknownFormatFlagsException{})
+	RegisterPOJO(&java_exception.IllegalFormatFlagsException{})
+	RegisterPOJO(&java_exception.IllegalFormatPrecisionException{})
+	RegisterPOJO(&java_exception.IllegalFormatCodePointException{})
+	RegisterPOJO(&java_exception.MissingFormatArgumentException{})
+	RegisterPOJO(&java_exception.MissingFormatWidthException{})
 }
diff --git a/java_exception/IOException.go b/java_exception/arithmetic_exception.go
similarity index 61%
copy from java_exception/IOException.go
copy to java_exception/arithmetic_exception.go
index 0276452..b32aac6 100644
--- a/java_exception/IOException.go
+++ b/java_exception/arithmetic_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 rzy1107@163.com
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type ArithmeticException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewArithmeticException(detailMessage string) *ArithmeticException {
+	return &ArithmeticException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e ArithmeticException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (ArithmeticException) JavaClassName() string {
+	return "java.lang.ArithmeticException"
 }
diff --git a/java_exception/array_index_out_of_bounds_exception.go b/java_exception/array_index_out_of_bounds_exception.go
index 0292126..2ab958b 100644
--- a/java_exception/array_index_out_of_bounds_exception.go
+++ b/java_exception/array_index_out_of_bounds_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []ArrayIndexOutOfBoundsException
-	Cause                *ArrayIndexOutOfBoundsException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewArrayIndexOutOfBoundsException(detailMessage string) *ArrayIndexOutOfBoundsException {
diff --git a/java_exception/array_store_exception.go b/java_exception/array_store_exception.go
index e384c45..8e348f1 100644
--- a/java_exception/array_store_exception.go
+++ b/java_exception/array_store_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []ArrayStoreException
-	Cause                *ArrayStoreException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewArrayStoreException(detailMessage string) *ArrayStoreException {
diff --git a/java_exception/IOException.go b/java_exception/backing_store_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/backing_store_exception.go
index 0276452..1b8a9ef 100644
--- a/java_exception/IOException.go
+++ b/java_exception/backing_store_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type BackingStoreException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewBackingStoreException(detailMessage string) *BackingStoreException {
+	return &BackingStoreException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e BackingStoreException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (BackingStoreException) JavaClassName() string {
+	return "java.util.prefs.BackingStoreException"
 }
diff --git a/java_exception/IOException.go b/java_exception/broken_barrier_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/broken_barrier_exception.go
index 0276452..736ba6e 100644
--- a/java_exception/IOException.go
+++ b/java_exception/broken_barrier_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type BrokenBarrierException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewBrokenBarrierException(detailMessage string) *BrokenBarrierException {
+	return &BrokenBarrierException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e BrokenBarrierException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (BrokenBarrierException) JavaClassName() string {
+	return "java.util.concurrent.BrokenBarrierException"
 }
diff --git a/java_exception/IOException.go b/java_exception/cancellation_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/cancellation_exception.go
index 0276452..644a024 100644
--- a/java_exception/IOException.go
+++ b/java_exception/cancellation_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type CancellationException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewCancellationException(detailMessage string) *CancellationException {
+	return &CancellationException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e CancellationException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (CancellationException) JavaClassName() string {
+	return "java.util.concurrent.CancellationException"
 }
diff --git a/java_exception/class_not_found_exception.go b/java_exception/class_not_found_exception.go
new file mode 100644
index 0000000..22687e2
--- /dev/null
+++ b/java_exception/class_not_found_exception.go
@@ -0,0 +1,36 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type ClassNotFoundException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	Ex                   Throwabler
+}
+
+func NewClassNotFoundException(detailMessage string, ex Throwabler) *ClassNotFoundException {
+	return &ClassNotFoundException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}, Ex: ex}
+}
+
+func (e ClassNotFoundException) Error() string {
+	return e.DetailMessage
+}
+
+func (ClassNotFoundException) JavaClassName() string {
+	return "java.lang.ClassNotFoundException"
+}
diff --git a/java_exception/classc_cast_exception.go b/java_exception/classc_cast_exception.go
index 760e6cf..f82666e 100644
--- a/java_exception/classc_cast_exception.go
+++ b/java_exception/classc_cast_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []ClassCastException
-	Cause                *ClassCastException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewClassCastException(detailMessage string) *ClassCastException {
diff --git a/java_exception/clone_not_supported_exception.go b/java_exception/clone_not_supported_exception.go
new file mode 100644
index 0000000..5df2edc
--- /dev/null
+++ b/java_exception/clone_not_supported_exception.go
@@ -0,0 +1,39 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+////////////////////////////
+// CloneNotSupportedException
+////////////////////////////
+
+type CloneNotSupportedException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewCloneNotSupportedException(detailMessage string) *CloneNotSupportedException {
+	return &CloneNotSupportedException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e CloneNotSupportedException) Error() string {
+	return e.DetailMessage
+}
+
+func (CloneNotSupportedException) JavaClassName() string {
+	return "java.lang.CloneNotSupportedException"
+}
diff --git a/java_exception/completion_exception.go b/java_exception/completion_exception.go
index 6731387..76a49b4 100644
--- a/java_exception/completion_exception.go
+++ b/java_exception/completion_exception.go
@@ -17,9 +17,9 @@
 type CompletionException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *Throwable
+	Cause                Throwabler
 }
 
 func (e CompletionException) Error() string {
diff --git a/java_exception/concurrent_modification_exception.go b/java_exception/concurrent_modification_exception.go
index 6fa334c..ce9a185 100644
--- a/java_exception/concurrent_modification_exception.go
+++ b/java_exception/concurrent_modification_exception.go
@@ -17,9 +17,9 @@
 type ConcurrentModificationException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *ConcurrentModificationException
+	Cause                Throwabler
 }
 
 func (e ConcurrentModificationException) Error() string {
diff --git a/java_exception/IOException.go b/java_exception/data_format_exception.go
similarity index 61%
copy from java_exception/IOException.go
copy to java_exception/data_format_exception.go
index 0276452..f9e6a2a 100644
--- a/java_exception/IOException.go
+++ b/java_exception/data_format_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type DataFormatException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewDataFormatException(detailMessage string) *DataFormatException {
+	return &DataFormatException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e DataFormatException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (DataFormatException) JavaClassName() string {
+	return "java.util.zip.DataFormatException"
 }
diff --git a/java_exception/IOException.go b/java_exception/date_time_exception.go
similarity index 62%
copy from java_exception/IOException.go
copy to java_exception/date_time_exception.go
index 0276452..c73dd96 100644
--- a/java_exception/IOException.go
+++ b/java_exception/date_time_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type DateTimeException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewDateTimeException(detailMessage string) *DateTimeException {
+	return &DateTimeException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e DateTimeException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (DateTimeException) JavaClassName() string {
+	return "java.time.DateTimeException"
 }
diff --git a/java_exception/date_time_parse_exception.go b/java_exception/date_time_parse_exception.go
new file mode 100644
index 0000000..267861e
--- /dev/null
+++ b/java_exception/date_time_parse_exception.go
@@ -0,0 +1,37 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type DateTimeParseException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	ParsedString         string
+	ErrorIndex           int32
+}
+
+func NewDateTimeParseException(detailMessage string, parsedString string, errorIndex int32) *DateTimeParseException {
+	return &DateTimeParseException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}, ParsedString: parsedString, ErrorIndex: errorIndex}
+}
+
+func (e DateTimeParseException) Error() string {
+	return e.DetailMessage
+}
+
+func (DateTimeParseException) JavaClassName() string {
+	return "java.time.format.DateTimeParseException"
+}
diff --git a/java_exception/duplicate_format_flags_exception.go b/java_exception/duplicate_format_flags_exception.go
index 155b0b9..0b774c8 100644
--- a/java_exception/duplicate_format_flags_exception.go
+++ b/java_exception/duplicate_format_flags_exception.go
@@ -18,9 +18,9 @@
 	SerialVersionUID     int64
 	Flags                string
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *DuplicateFormatFlagsException
+	Cause                Throwabler
 }
 
 func (e DuplicateFormatFlagsException) Error() string {
diff --git a/java_exception/empty_stack_exception.go b/java_exception/empty_stack_exception.go
index 3249f66..f3b57ad 100644
--- a/java_exception/empty_stack_exception.go
+++ b/java_exception/empty_stack_exception.go
@@ -17,9 +17,9 @@
 type EmptyStackException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *EmptyStackException
+	Cause                Throwabler
 }
 
 func (e EmptyStackException) Error() string {
diff --git a/java_exception/enum_constant_not_present_exception.go b/java_exception/enum_constant_not_present_exception.go
index e8d44ee..e4c1721 100644
--- a/java_exception/enum_constant_not_present_exception.go
+++ b/java_exception/enum_constant_not_present_exception.go
@@ -20,8 +20,8 @@
 	StackTrace           []StackTraceElement
 	ConstantName         string
 	EnumType             Class
-	SuppressedExceptions []EnumConstantNotPresentException
-	Cause                *EnumConstantNotPresentException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewEnumConstantNotPresentException(detailMessage string) *EnumConstantNotPresentException {
diff --git a/java_exception/EOF_exception.go b/java_exception/eof_exception.go
similarity index 93%
rename from java_exception/EOF_exception.go
rename to java_exception/eof_exception.go
index 214454f..1a21ff7 100644
--- a/java_exception/EOF_exception.go
+++ b/java_exception/eof_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []EOFException
-	Cause                *EOFException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewEOFException(detailMessage string) *EOFException {
diff --git a/java_exception/java_exception.go b/java_exception/exception.go
similarity index 87%
rename from java_exception/java_exception.go
rename to java_exception/exception.go
index 3899ad1..2a458a2 100644
--- a/java_exception/java_exception.go
+++ b/java_exception/exception.go
@@ -15,15 +15,24 @@
 package java_exception
 
 ////////////////////////////
+// Throwable interface
+////////////////////////////
+
+type Throwabler interface {
+	Error() string
+	JavaClassName() string
+}
+
+////////////////////////////
 // Throwable
 ////////////////////////////
 
 type Throwable struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Throwable
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *Throwable
+	Cause                Throwabler
 }
 
 func NewThrowable(detailMessage string) *Throwable {
@@ -45,9 +54,9 @@
 type Exception struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *Exception
+	Cause                Throwabler
 }
 
 func NewException(detailMessage string) *Exception {
diff --git a/java_exception/IOException.go b/java_exception/execution_exception.go
similarity index 61%
copy from java_exception/IOException.go
copy to java_exception/execution_exception.go
index 0276452..1c04dc8 100644
--- a/java_exception/IOException.go
+++ b/java_exception/execution_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type ExecutionException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewExecutionException(detailMessage string) *ExecutionException {
+	return &ExecutionException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e ExecutionException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (ExecutionException) JavaClassName() string {
+	return "java.util.concurrent.ExecutionException"
 }
diff --git a/java_exception/file_not_found_exception.go b/java_exception/file_not_found_exception.go
index 0d0410d..84fc123 100644
--- a/java_exception/file_not_found_exception.go
+++ b/java_exception/file_not_found_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []FileNotFoundException
-	Cause                *FileNotFoundException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewFileNotFoundException(detailMessage string) *FileNotFoundException {
diff --git a/java_exception/IOException.go b/java_exception/formatter_closed_exception.go
similarity index 62%
copy from java_exception/IOException.go
copy to java_exception/formatter_closed_exception.go
index 0276452..75c4612 100644
--- a/java_exception/IOException.go
+++ b/java_exception/formatter_closed_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type FormatterClosedException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewFormatterClosedException() *FormatterClosedException {
+	return &FormatterClosedException{StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e FormatterClosedException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (FormatterClosedException) JavaClassName() string {
+	return "java.util.FormatterClosedException"
 }
diff --git a/java_exception/IOException.go b/java_exception/illegal_access_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/illegal_access_exception.go
index 0276452..5dd684a 100644
--- a/java_exception/IOException.go
+++ b/java_exception/illegal_access_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type IllegalAccessException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewIllegalAccessException(detailMessage string) *IllegalAccessException {
+	return &IllegalAccessException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e IllegalAccessException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (IllegalAccessException) JavaClassName() string {
+	return "java.lang.IllegalAccessException"
 }
diff --git a/java_exception/illegal_argument_exception.go b/java_exception/illegal_argument_exception.go
index 1ab2ff0..e4f401a 100644
--- a/java_exception/illegal_argument_exception.go
+++ b/java_exception/illegal_argument_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []IllegalArgumentException
-	Cause                *IllegalArgumentException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewIllegalArgumentException(detailMessage string) *IllegalArgumentException {
diff --git a/java_exception/illegal_classFormat_exception.go b/java_exception/illegal_classFormat_exception.go
new file mode 100644
index 0000000..0913a4d
--- /dev/null
+++ b/java_exception/illegal_classFormat_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type IllegalClassFormatException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewIllegalClassFormatException(detailMessage string) *IllegalClassFormatException {
+	return &IllegalClassFormatException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e IllegalClassFormatException) Error() string {
+	return e.DetailMessage
+}
+
+func (IllegalClassFormatException) JavaClassName() string {
+	return "java.lang.instrument.IllegalClassFormatException"
+}
diff --git a/java_exception/illegal_format_code_point_exception.go b/java_exception/illegal_format_code_point_exception.go
new file mode 100644
index 0000000..355a7af
--- /dev/null
+++ b/java_exception/illegal_format_code_point_exception.go
@@ -0,0 +1,38 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+import "fmt"
+
+type IllegalFormatCodePointException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	C                    int32
+}
+
+func NewIllegalFormatCodePointException(c int32) *IllegalFormatCodePointException {
+	return &IllegalFormatCodePointException{C: c, StackTrace: []StackTraceElement{}}
+}
+
+func (e IllegalFormatCodePointException) Error() string {
+	return fmt.Sprintf("Code point = %#x", e.C)
+}
+
+func (IllegalFormatCodePointException) JavaClassName() string {
+	return "java.util.IllegalFormatCodePointException"
+}
diff --git a/java_exception/illegal_format_conversion_exception.go b/java_exception/illegal_format_conversion_exception.go
index c8592a0..6a32f5d 100644
--- a/java_exception/illegal_format_conversion_exception.go
+++ b/java_exception/illegal_format_conversion_exception.go
@@ -21,9 +21,9 @@
 	C                    string
 	Arg                  Class
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IllegalFormatConversionException
+	Cause                Throwabler
 }
 
 func (e IllegalFormatConversionException) Error() string {
diff --git a/java_exception/illegal_format_flags_exception.go b/java_exception/illegal_format_flags_exception.go
new file mode 100644
index 0000000..434ae77
--- /dev/null
+++ b/java_exception/illegal_format_flags_exception.go
@@ -0,0 +1,38 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+import "fmt"
+
+type IllegalFormatFlagsException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	Flags                string
+}
+
+func NewIllegalFormatFlagsException(flags string) *IllegalFormatFlagsException {
+	return &IllegalFormatFlagsException{Flags: flags, StackTrace: []StackTraceElement{}}
+}
+
+func (e IllegalFormatFlagsException) Error() string {
+	return fmt.Sprintf("Flags = '%s'", e.Flags)
+}
+
+func (IllegalFormatFlagsException) JavaClassName() string {
+	return "java.util.IllegalFormatFlagsException"
+}
diff --git a/java_exception/illegal_format_precision_exception.go b/java_exception/illegal_format_precision_exception.go
new file mode 100644
index 0000000..3d4da49
--- /dev/null
+++ b/java_exception/illegal_format_precision_exception.go
@@ -0,0 +1,38 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+import "strconv"
+
+type IllegalFormatPrecisionException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	P                    int32
+}
+
+func NewIllegalFormatPrecisionException(p int32) *IllegalFormatPrecisionException {
+	return &IllegalFormatPrecisionException{P: p, StackTrace: []StackTraceElement{}}
+}
+
+func (e IllegalFormatPrecisionException) Error() string {
+	return strconv.Itoa(int(e.P))
+}
+
+func (IllegalFormatPrecisionException) JavaClassName() string {
+	return "java.util.IllegalFormatPrecisionException"
+}
diff --git a/java_exception/illegal_format_width_exception.go b/java_exception/illegal_format_width_exception.go
index 68b46ff..a548453 100644
--- a/java_exception/illegal_format_width_exception.go
+++ b/java_exception/illegal_format_width_exception.go
@@ -20,9 +20,9 @@
 	SerialVersionUID     int64
 	W                    int
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IllegalFormatWidthException
+	Cause                Throwabler
 }
 
 func (e IllegalFormatWidthException) Error() string {
diff --git a/java_exception/illegal_monitor_state_exception.go b/java_exception/illegal_monitor_state_exception.go
index 1b56679..90a1b5e 100644
--- a/java_exception/illegal_monitor_state_exception.go
+++ b/java_exception/illegal_monitor_state_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []IllegalMonitorStateException
-	Cause                *IllegalMonitorStateException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewIllegalMonitorStateException(detailMessage string) *IllegalMonitorStateException {
diff --git a/java_exception/illegal_state_exception.go b/java_exception/illegal_state_exception.go
index d573396..7b91210 100644
--- a/java_exception/illegal_state_exception.go
+++ b/java_exception/illegal_state_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []IllegalStateException
-	Cause                *IllegalStateException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewIllegalStateException(detailMessage string) *IllegalStateException {
diff --git a/java_exception/illegal_thread_state_exception.go b/java_exception/illegal_thread_state_exception.go
index c91c3b5..05bbd37 100644
--- a/java_exception/illegal_thread_state_exception.go
+++ b/java_exception/illegal_thread_state_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []IllegalThreadStateException
-	Cause                *IllegalThreadStateException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewIllegalThreadStateException(detailMessage string) *IllegalThreadStateException {
diff --git a/java_exception/illformed_locale_exception.go b/java_exception/illformed_locale_exception.go
index 2857fd6..c22897e 100644
--- a/java_exception/illformed_locale_exception.go
+++ b/java_exception/illformed_locale_exception.go
@@ -18,9 +18,9 @@
 	_errIdx              int
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IllformedLocaleException
+	Cause                Throwabler
 }
 
 func (e IllformedLocaleException) Error() string {
diff --git a/java_exception/index_out_of_bounds_exception.go b/java_exception/index_out_of_bounds_exception.go
index 3422cca..ff1d656 100644
--- a/java_exception/index_out_of_bounds_exception.go
+++ b/java_exception/index_out_of_bounds_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []IndexOutOfBoundsException
-	Cause                *IndexOutOfBoundsException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewIndexOutOfBoundsException(detailMessage string) *IndexOutOfBoundsException {
diff --git a/java_exception/IOException.go b/java_exception/input_mismatch_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/input_mismatch_exception.go
index 0276452..20d0348 100644
--- a/java_exception/IOException.go
+++ b/java_exception/input_mismatch_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type InputMismatchException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewInputMismatchException(detailMessage string) *InputMismatchException {
+	return &InputMismatchException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e InputMismatchException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (InputMismatchException) JavaClassName() string {
+	return "java.util.InputMismatchException"
 }
diff --git a/java_exception/IOException.go b/java_exception/instantiation_exception.go
similarity index 60%
copy from java_exception/IOException.go
copy to java_exception/instantiation_exception.go
index 0276452..9ebd372 100644
--- a/java_exception/IOException.go
+++ b/java_exception/instantiation_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type InstantiationException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewInstantiationException(detailMessage string) *InstantiationException {
+	return &InstantiationException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e InstantiationException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (InstantiationException) JavaClassName() string {
+	return "java.lang.InstantiationException"
 }
diff --git a/java_exception/interrupted_exception.go b/java_exception/interrupted_exception.go
new file mode 100644
index 0000000..d2135d3
--- /dev/null
+++ b/java_exception/interrupted_exception.go
@@ -0,0 +1,39 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+////////////////////////////
+// InterruptedException
+////////////////////////////
+
+type InterruptedException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewInterruptedException(detailMessage string) *InterruptedException {
+	return &InterruptedException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e InterruptedException) Error() string {
+	return e.DetailMessage
+}
+
+func (InterruptedException) JavaClassName() string {
+	return "java.lang.InterruptedException"
+}
diff --git a/java_exception/interrupted_io_exception.go b/java_exception/interrupted_io_exception.go
new file mode 100644
index 0000000..a307438
--- /dev/null
+++ b/java_exception/interrupted_io_exception.go
@@ -0,0 +1,40 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+////////////////////////////
+// InterruptedIOException
+////////////////////////////
+
+type InterruptedIOException struct {
+	SerialVersionUID     int64
+	BytesTransferred     int32
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewInterruptedIOException(detailMessage string) *InterruptedIOException {
+	return &InterruptedIOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e InterruptedIOException) Error() string {
+	return e.DetailMessage
+}
+
+func (InterruptedIOException) JavaClassName() string {
+	return "java.io.InterruptedIOException"
+}
diff --git a/java_exception/invalid_class_exception.go b/java_exception/invalid_class_exception.go
index 7f29325..badc426 100644
--- a/java_exception/invalid_class_exception.go
+++ b/java_exception/invalid_class_exception.go
@@ -21,8 +21,8 @@
 	DetailMessage        string
 	StackTrace           []StackTraceElement
 	Classname            string
-	SuppressedExceptions []InvalidClassException
-	Cause                *InvalidClassException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewInvalidClassException(classname string, detailMessage string) *InvalidClassException {
diff --git a/java_exception/invalid_object_exception.go b/java_exception/invalid_object_exception.go
index bf1adec..4f9b2ff 100644
--- a/java_exception/invalid_object_exception.go
+++ b/java_exception/invalid_object_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []InvalidObjectException
-	Cause                *InvalidObjectException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewInvalidObjectException(detailMessage string) *InvalidObjectException {
diff --git a/java_exception/invalid_preferences_format_exception.go b/java_exception/invalid_preferences_format_exception.go
new file mode 100644
index 0000000..6b017fd
--- /dev/null
+++ b/java_exception/invalid_preferences_format_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type InvalidPreferencesFormatException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewInvalidPreferencesFormatException(detailMessage string) *InvalidPreferencesFormatException {
+	return &InvalidPreferencesFormatException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e InvalidPreferencesFormatException) Error() string {
+	return e.DetailMessage
+}
+
+func (InvalidPreferencesFormatException) JavaClassName() string {
+	return "java.util.prefs.InvalidPreferencesFormatException"
+}
diff --git a/java_exception/invalid_properties_format_exception.go b/java_exception/invalid_properties_format_exception.go
new file mode 100644
index 0000000..78276ac
--- /dev/null
+++ b/java_exception/invalid_properties_format_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type InvalidPropertiesFormatException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewInvalidPropertiesFormatException(detailMessage string) *InvalidPropertiesFormatException {
+	return &InvalidPropertiesFormatException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e InvalidPropertiesFormatException) Error() string {
+	return e.DetailMessage
+}
+
+func (InvalidPropertiesFormatException) JavaClassName() string {
+	return "java.util.InvalidPropertiesFormatException"
+}
diff --git a/java_exception/invocation_target_exception.go b/java_exception/invocation_target_exception.go
new file mode 100644
index 0000000..c5f0726
--- /dev/null
+++ b/java_exception/invocation_target_exception.go
@@ -0,0 +1,36 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type InvocationTargetException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	Target               Throwabler
+}
+
+func NewInvocationTargetException(target Throwabler, detailMessage string) *InvocationTargetException {
+	return &InvocationTargetException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}, Target: target}
+}
+
+func (e InvocationTargetException) Error() string {
+	return e.DetailMessage
+}
+
+func (InvocationTargetException) JavaClassName() string {
+	return "java.lang.reflect.InvocationTargetException"
+}
diff --git a/java_exception/IOException.go b/java_exception/io_exception.go
similarity index 93%
rename from java_exception/IOException.go
rename to java_exception/io_exception.go
index 0276452..7afd606 100644
--- a/java_exception/IOException.go
+++ b/java_exception/io_exception.go
@@ -17,9 +17,9 @@
 type IOException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
 func NewIOException(detailMessage string) *IOException {
diff --git a/java_exception/EOF_exception.go b/java_exception/jar_exception.go
similarity index 66%
copy from java_exception/EOF_exception.go
copy to java_exception/jar_exception.go
index 214454f..55d87f8 100644
--- a/java_exception/EOF_exception.go
+++ b/java_exception/jar_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 summerbuger@gmail.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type EOFException struct {
+type JarException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []EOFException
-	Cause                *EOFException
+	Cause                Throwabler
 }
 
-func NewEOFException(detailMessage string) *EOFException {
-	return &EOFException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewJarException(detailMessage string) *JarException {
+	return &JarException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e EOFException) Error() string {
+func (e JarException) Error() string {
 	return e.DetailMessage
 }
 
-func (EOFException) JavaClassName() string {
-	return "java.io.EOFException"
+func (JarException) JavaClassName() string {
+	return "java.util.jar.JarException"
 }
diff --git a/java_exception/lambda_conversion_exception.go b/java_exception/lambda_conversion_exception.go
new file mode 100644
index 0000000..bc4ba1b
--- /dev/null
+++ b/java_exception/lambda_conversion_exception.go
@@ -0,0 +1,39 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+////////////////////////////
+// LambdaConversionException
+////////////////////////////
+
+type LambdaConversionException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewLambdaConversionException(detailMessage string) *LambdaConversionException {
+	return &LambdaConversionException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e LambdaConversionException) Error() string {
+	return e.DetailMessage
+}
+
+func (LambdaConversionException) JavaClassName() string {
+	return "java.lang.invoke.LambdaConversionException"
+}
diff --git a/java_exception/java_malformed_parameterized_type_exception.go b/java_exception/malformed_parameterized_type_exception.go
similarity index 92%
rename from java_exception/java_malformed_parameterized_type_exception.go
rename to java_exception/malformed_parameterized_type_exception.go
index 83d14c1..a79dfc9 100644
--- a/java_exception/java_malformed_parameterized_type_exception.go
+++ b/java_exception/malformed_parameterized_type_exception.go
@@ -17,9 +17,9 @@
 type MalformedParameterizedTypeException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *MalformedParameterizedTypeException
+	Cause                Throwabler
 }
 
 func (e MalformedParameterizedTypeException) Error() string {
diff --git a/java_exception/java_malformed_parameters_exception.go b/java_exception/malformed_parameters_exception.go
similarity index 92%
rename from java_exception/java_malformed_parameters_exception.go
rename to java_exception/malformed_parameters_exception.go
index 212cd2a..c0fddf8 100644
--- a/java_exception/java_malformed_parameters_exception.go
+++ b/java_exception/malformed_parameters_exception.go
@@ -17,9 +17,9 @@
 type MalformedParametersException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *MalformedParametersException
+	Cause                Throwabler
 }
 
 func (e MalformedParametersException) Error() string {
diff --git a/java_exception/missing_format_argument_exception.go b/java_exception/missing_format_argument_exception.go
new file mode 100644
index 0000000..94112da
--- /dev/null
+++ b/java_exception/missing_format_argument_exception.go
@@ -0,0 +1,38 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+import "fmt"
+
+type MissingFormatArgumentException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	S                    string
+}
+
+func NewMissingFormatArgumentException(s string) *MissingFormatArgumentException {
+	return &MissingFormatArgumentException{S: s, StackTrace: []StackTraceElement{}}
+}
+
+func (e MissingFormatArgumentException) Error() string {
+	return fmt.Sprintf("Format specifier '%s'", e.S)
+}
+
+func (MissingFormatArgumentException) JavaClassName() string {
+	return "java.util.MissingFormatArgumentException"
+}
diff --git a/java_exception/missing_format_width_exception.go b/java_exception/missing_format_width_exception.go
new file mode 100644
index 0000000..03b1a59
--- /dev/null
+++ b/java_exception/missing_format_width_exception.go
@@ -0,0 +1,36 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type MissingFormatWidthException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	S                    string
+}
+
+func NewMissingFormatWidthException(s string) *MissingFormatWidthException {
+	return &MissingFormatWidthException{S: s, StackTrace: []StackTraceElement{}}
+}
+
+func (e MissingFormatWidthException) Error() string {
+	return e.S
+}
+
+func (MissingFormatWidthException) JavaClassName() string {
+	return "java.util.MissingFormatWidthException"
+}
diff --git a/java_exception/missing_resource_exception.go b/java_exception/missing_resource_exception.go
index e2fbcb2..4cbd82f 100644
--- a/java_exception/missing_resource_exception.go
+++ b/java_exception/missing_resource_exception.go
@@ -19,9 +19,9 @@
 	Key                  string
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *MissingResourceException
+	Cause                Throwabler
 }
 
 func (e MissingResourceException) Error() string {
diff --git a/java_exception/negative_array_size_exception.go b/java_exception/negative_array_size_exception.go
new file mode 100644
index 0000000..84d3608
--- /dev/null
+++ b/java_exception/negative_array_size_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 rzy1107@163.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type NegativeArraySizeException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	StackTrace           []StackTraceElement
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
+}
+
+func NewNegativeArraySizeException(detailMessage string) *NegativeArraySizeException {
+	return &NegativeArraySizeException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e NegativeArraySizeException) Error() string {
+	return e.DetailMessage
+}
+
+func (NegativeArraySizeException) JavaClassName() string {
+	return "java.lang.NegativeArraySizeException"
+}
diff --git a/java_exception/no_such_element_exception.go b/java_exception/no_such_element_exception.go
index 2887b72..29490a4 100644
--- a/java_exception/no_such_element_exception.go
+++ b/java_exception/no_such_element_exception.go
@@ -17,9 +17,9 @@
 type NoSuchElementException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *NoSuchElementException
+	Cause                Throwabler
 }
 
 func (e NoSuchElementException) Error() string {
diff --git a/java_exception/IOException.go b/java_exception/no_such_field_exception.go
similarity index 61%
copy from java_exception/IOException.go
copy to java_exception/no_such_field_exception.go
index 0276452..fc21d8c 100644
--- a/java_exception/IOException.go
+++ b/java_exception/no_such_field_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type NoSuchFieldException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewNoSuchFieldException(detailMessage string) *NoSuchFieldException {
+	return &NoSuchFieldException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e NoSuchFieldException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (NoSuchFieldException) JavaClassName() string {
+	return "java.lang.NoSuchFieldException"
 }
diff --git a/java_exception/IOException.go b/java_exception/no_such_method_exception.go
similarity index 61%
copy from java_exception/IOException.go
copy to java_exception/no_such_method_exception.go
index 0276452..efb81ea 100644
--- a/java_exception/IOException.go
+++ b/java_exception/no_such_method_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type NoSuchMethodException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewNoSuchMethodException(detailMessage string) *NoSuchMethodException {
+	return &NoSuchMethodException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e NoSuchMethodException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (NoSuchMethodException) JavaClassName() string {
+	return "java.lang.NoSuchMethodException"
 }
diff --git a/java_exception/not_active_exception.go b/java_exception/not_active_exception.go
index 56b27ed..6542187 100644
--- a/java_exception/not_active_exception.go
+++ b/java_exception/not_active_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []NotActiveException
-	Cause                *NotActiveException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewNotActiveException(detailMessage string) *NotActiveException {
diff --git a/java_exception/not_serializable_exception.go b/java_exception/not_serializable_exception.go
index bfcaa79..56fe782 100644
--- a/java_exception/not_serializable_exception.go
+++ b/java_exception/not_serializable_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []NotSerializableException
-	Cause                *NotSerializableException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewNotSerializableException(detailMessage string) *NotActiveException {
diff --git a/java_exception/null_pointer_exception.go b/java_exception/null_pointer_exception.go
index 502305a..aafd28a 100644
--- a/java_exception/null_pointer_exception.go
+++ b/java_exception/null_pointer_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []NullPointerException
-	Cause                *NullPointerException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewNullPointerException(detailMessage string) *NullPointerException {
diff --git a/java_exception/number_format_exception.go b/java_exception/number_format_exception.go
index bf6e0c7..928a93e 100644
--- a/java_exception/number_format_exception.go
+++ b/java_exception/number_format_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []NumberFormatException
-	Cause                *NumberFormatException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewNumberFormatException(detailMessage string) *NumberFormatException {
diff --git a/java_exception/object_stream_exception.go b/java_exception/object_stream_exception.go
index 863a485..8fa0cd9 100644
--- a/java_exception/object_stream_exception.go
+++ b/java_exception/object_stream_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []ObjectStreamException
-	Cause                *ObjectStreamException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewObjectStreamException(detailMessage string) *ObjectStreamException {
diff --git a/java_exception/optional_data_exception.go b/java_exception/optional_data_exception.go
index 3059b1d..186ca01 100644
--- a/java_exception/optional_data_exception.go
+++ b/java_exception/optional_data_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []OptionalDataException
-	Cause                *OptionalDataException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 	Eof                  bool
 	Length               int
 }
diff --git a/java_exception/reflective_operation_exception.go b/java_exception/reflective_operation_exception.go
new file mode 100644
index 0000000..e604f6e
--- /dev/null
+++ b/java_exception/reflective_operation_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type ReflectiveOperationException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewReflectiveOperationException(detailMessage string) *ReflectiveOperationException {
+	return &ReflectiveOperationException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e ReflectiveOperationException) Error() string {
+	return e.DetailMessage
+}
+
+func (ReflectiveOperationException) JavaClassName() string {
+	return "java.lang.ReflectiveOperationException"
+}
diff --git a/java_exception/rejected_execution_exception.go b/java_exception/rejected_execution_exception.go
index ee29f66..ffbe608 100644
--- a/java_exception/rejected_execution_exception.go
+++ b/java_exception/rejected_execution_exception.go
@@ -17,9 +17,9 @@
 type RejectedExecutionException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *RejectedExecutionException
+	Cause                Throwabler
 }
 
 func (e RejectedExecutionException) Error() string {
diff --git a/java_exception/runtime_exception.go b/java_exception/runtime_exception.go
index 701c052..eff3e3f 100644
--- a/java_exception/runtime_exception.go
+++ b/java_exception/runtime_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []RuntimeException
-	Cause                *RuntimeException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewRuntimeException(detailMessage string) *RuntimeException {
diff --git a/java_exception/security_exception.go b/java_exception/security_exception.go
index 4e0f627..e08b4bd 100644
--- a/java_exception/security_exception.go
+++ b/java_exception/security_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []SecurityException
-	Cause                *SecurityException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewSecurityException(detailMessage string) *SecurityException {
diff --git a/java_exception/stream_corrupted_exception.go b/java_exception/stream_corrupted_exception.go
index e9cbec4..2c295ee 100644
--- a/java_exception/stream_corrupted_exception.go
+++ b/java_exception/stream_corrupted_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []StreamCorruptedException
-	Cause                *StreamCorruptedException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewStreamCorruptedException(detailMessage string) *StreamCorruptedException {
diff --git a/java_exception/string_index_out_of_bounds_exception.go b/java_exception/string_index_out_of_bounds_exception.go
index cb6a1ee..1888e02 100644
--- a/java_exception/string_index_out_of_bounds_exception.go
+++ b/java_exception/string_index_out_of_bounds_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []StringIndexOutOfBoundsException
-	Cause                *StringIndexOutOfBoundsException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewStringIndexOutOfBoundsException(detailMessage string) *StringIndexOutOfBoundsException {
diff --git a/java_exception/sync_failed_exception.go b/java_exception/sync_failed_exception.go
index 4ca67e8..dd3ea37 100644
--- a/java_exception/sync_failed_exception.go
+++ b/java_exception/sync_failed_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []SyncFailedException
-	Cause                *SyncFailedException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewSyncFailedException(detailMessage string) *SyncFailedException {
diff --git a/java_exception/IOException.go b/java_exception/timeout_exception.go
similarity index 62%
copy from java_exception/IOException.go
copy to java_exception/timeout_exception.go
index 0276452..72b0b97 100644
--- a/java_exception/IOException.go
+++ b/java_exception/timeout_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 ckex868@vip.qq.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type IOException struct {
+type TimeoutException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []IOException
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *IOException
+	Cause                Throwabler
 }
 
-func NewIOException(detailMessage string) *IOException {
-	return &IOException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewTimeoutException(detailMessage string) *TimeoutException {
+	return &TimeoutException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e IOException) Error() string {
+func (e TimeoutException) Error() string {
 	return e.DetailMessage
 }
 
-func (IOException) JavaClassName() string {
-	return "java.io.IOException"
+func (TimeoutException) JavaClassName() string {
+	return "java.util.concurrent.TimeoutException"
 }
diff --git a/java_exception/too_many_listeners_exception.go b/java_exception/too_many_listeners_exception.go
new file mode 100644
index 0000000..961f93e
--- /dev/null
+++ b/java_exception/too_many_listeners_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type TooManyListenersException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewTooManyListenersException(detailMessage string) *TooManyListenersException {
+	return &TooManyListenersException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e TooManyListenersException) Error() string {
+	return e.DetailMessage
+}
+
+func (TooManyListenersException) JavaClassName() string {
+	return "java.util.TooManyListenersException"
+}
diff --git a/java_exception/java_type_not_present_exception.go b/java_exception/type_not_present_exception.go
similarity index 94%
rename from java_exception/java_type_not_present_exception.go
rename to java_exception/type_not_present_exception.go
index 66a261a..2a7d355 100644
--- a/java_exception/java_type_not_present_exception.go
+++ b/java_exception/type_not_present_exception.go
@@ -18,9 +18,9 @@
 	TypeName             string
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *Throwable
+	Cause                Throwabler
 }
 
 func (e TypeNotPresentException) Error() string {
diff --git a/java_exception/unchecked_IO_exception.go b/java_exception/unchecked_IO_exception.go
index e8cc29d..769c025 100644
--- a/java_exception/unchecked_IO_exception.go
+++ b/java_exception/unchecked_IO_exception.go
@@ -18,11 +18,11 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []UncheckedIOException
-	Cause                *IOException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
-func NewUncheckedIOException(detailMessage string, cause *IOException) (result *UncheckedIOException, err error) {
+func NewUncheckedIOException(detailMessage string, cause Throwabler) (result *UncheckedIOException, err error) {
 	if cause == nil {
 		return nil, NullPointerException{}
 	}
diff --git a/java_exception/java_undeclared_throwable_exception.go b/java_exception/undeclared_throwable_exception.go
similarity index 91%
rename from java_exception/java_undeclared_throwable_exception.go
rename to java_exception/undeclared_throwable_exception.go
index 961575e..83ac80d 100644
--- a/java_exception/java_undeclared_throwable_exception.go
+++ b/java_exception/undeclared_throwable_exception.go
@@ -17,10 +17,10 @@
 type UndeclaredThrowableException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *Throwable
-	UndeclaredThrowable  Throwable
+	Cause                Throwabler
+	UndeclaredThrowable  Throwabler
 }
 
 func (e UndeclaredThrowableException) Error() string {
@@ -30,6 +30,7 @@
 func (UndeclaredThrowableException) JavaClassName() string {
 	return "java.lang.reflect.UndeclaredThrowableException"
 }
+
 func NewUndeclaredThrowableException(detailMessage string) *UndeclaredThrowableException {
 	return &UndeclaredThrowableException{DetailMessage: detailMessage, UndeclaredThrowable: Throwable{}}
 }
diff --git a/java_exception/unknown_format_conversion_exception.go b/java_exception/unknown_format_conversion_exception.go
new file mode 100644
index 0000000..56251fd
--- /dev/null
+++ b/java_exception/unknown_format_conversion_exception.go
@@ -0,0 +1,38 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+import "fmt"
+
+type UnknownFormatConversionException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	S                    string
+}
+
+func NewUnknownFormatConversionException(s string) *UnknownFormatConversionException {
+	return &UnknownFormatConversionException{S: s, StackTrace: []StackTraceElement{}}
+}
+
+func (e UnknownFormatConversionException) Error() string {
+	return fmt.Sprintf("Conversion = '%s'", e.S)
+}
+
+func (UnknownFormatConversionException) JavaClassName() string {
+	return "java.util.UnknownFormatConversionException"
+}
diff --git a/java_exception/unknown_format_flags_exception.go b/java_exception/unknown_format_flags_exception.go
new file mode 100644
index 0000000..1b3382a
--- /dev/null
+++ b/java_exception/unknown_format_flags_exception.go
@@ -0,0 +1,36 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type UnknownFormatFlagsException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+	Flags                string
+}
+
+func NewUnknownFormatFlagsException(flags string) *UnknownFormatFlagsException {
+	return &UnknownFormatFlagsException{Flags: flags, StackTrace: []StackTraceElement{}}
+}
+
+func (e UnknownFormatFlagsException) Error() string {
+	return "Flags = " + e.Flags
+}
+
+func (UnknownFormatFlagsException) JavaClassName() string {
+	return "java.util.UnknownFormatFlagsException"
+}
diff --git a/java_exception/unmodifiable_class_exception.go b/java_exception/unmodifiable_class_exception.go
new file mode 100644
index 0000000..791dcd4
--- /dev/null
+++ b/java_exception/unmodifiable_class_exception.go
@@ -0,0 +1,39 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+////////////////////////////
+// UnmodifiableClassException
+////////////////////////////
+
+type UnmodifiableClassException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewUnmodifiableClassException(detailMessage string) *UnmodifiableClassException {
+	return &UnmodifiableClassException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e UnmodifiableClassException) Error() string {
+	return e.DetailMessage
+}
+
+func (UnmodifiableClassException) JavaClassName() string {
+	return "java.lang.instrument.UnmodifiableClassException"
+}
diff --git a/java_exception/unsupported_operation_exception.go b/java_exception/unsupported_operation_exception.go
new file mode 100644
index 0000000..deaa307
--- /dev/null
+++ b/java_exception/unsupported_operation_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 rzy1107@163.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type UnsupportedOperationException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	StackTrace           []StackTraceElement
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
+}
+
+func NewUnsupportedOperationException(detailMessage string) *UnsupportedOperationException {
+	return &UnsupportedOperationException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e UnsupportedOperationException) Error() string {
+	return e.DetailMessage
+}
+
+func (UnsupportedOperationException) JavaClassName() string {
+	return "java.lang.UnsupportedOperationException"
+}
diff --git a/java_exception/unsupported_temporal_type_exception.go b/java_exception/unsupported_temporal_type_exception.go
new file mode 100644
index 0000000..44978c2
--- /dev/null
+++ b/java_exception/unsupported_temporal_type_exception.go
@@ -0,0 +1,35 @@
+// Copyright 2016-2019 Yincheng Fang
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java_exception
+
+type UnsupportedTemporalTypeException struct {
+	SerialVersionUID     int64
+	DetailMessage        string
+	SuppressedExceptions []Throwabler
+	StackTrace           []StackTraceElement
+	Cause                Throwabler
+}
+
+func NewUnsupportedTemporalTypeException(detailMessage string) *UnsupportedTemporalTypeException {
+	return &UnsupportedTemporalTypeException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+}
+
+func (e UnsupportedTemporalTypeException) Error() string {
+	return e.DetailMessage
+}
+
+func (UnsupportedTemporalTypeException) JavaClassName() string {
+	return "java.time.temporal.UnsupportedTemporalTypeException"
+}
diff --git a/java_exception/utf_data_format_exception.go b/java_exception/utf_data_format_exception.go
index 7806203..a34aa33 100644
--- a/java_exception/utf_data_format_exception.go
+++ b/java_exception/utf_data_format_exception.go
@@ -18,8 +18,8 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []UTFDataFormatException
-	Cause                *UTFDataFormatException
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
 func NewUTFDataFormatException(detailMessage string) *UTFDataFormatException {
diff --git a/java_exception/write_aborted_exception.go b/java_exception/write_aborted_exception.go
index d6c9f0e..1a4ee8b 100644
--- a/java_exception/write_aborted_exception.go
+++ b/java_exception/write_aborted_exception.go
@@ -18,12 +18,12 @@
 	SerialVersionUID     int64
 	DetailMessage        string
 	StackTrace           []StackTraceElement
-	Detail               *Exception
-	SuppressedExceptions []WriteAbortedException
-	Cause                *WriteAbortedException
+	Detail               Throwabler
+	SuppressedExceptions []Throwabler
+	Cause                Throwabler
 }
 
-func NewWriteAbortedException(detailMessage string, detail *Exception) *WriteAbortedException {
+func NewWriteAbortedException(detailMessage string, detail Throwabler) *WriteAbortedException {
 	return &WriteAbortedException{DetailMessage: detailMessage, StackTrace: nil,
 		Detail: detail}
 }
diff --git a/java_exception/java_wrong_method_type_exception.go b/java_exception/wrong_method_type_exception.go
similarity index 93%
rename from java_exception/java_wrong_method_type_exception.go
rename to java_exception/wrong_method_type_exception.go
index 4ac3f1b..e0fbccf 100644
--- a/java_exception/java_wrong_method_type_exception.go
+++ b/java_exception/wrong_method_type_exception.go
@@ -17,9 +17,9 @@
 type WrongMethodTypeException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
-	SuppressedExceptions []Exception
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	Cause                *WrongMethodTypeException
+	Cause                Throwabler
 }
 
 func (e WrongMethodTypeException) Error() string {
diff --git a/java_exception/EOF_exception.go b/java_exception/zip_exception.go
similarity index 66%
copy from java_exception/EOF_exception.go
copy to java_exception/zip_exception.go
index 214454f..073e813 100644
--- a/java_exception/EOF_exception.go
+++ b/java_exception/zip_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 summerbuger@gmail.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type EOFException struct {
+type ZipException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []EOFException
-	Cause                *EOFException
+	Cause                Throwabler
 }
 
-func NewEOFException(detailMessage string) *EOFException {
-	return &EOFException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewZipException(detailMessage string) *ZipException {
+	return &ZipException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e EOFException) Error() string {
+func (e ZipException) Error() string {
 	return e.DetailMessage
 }
 
-func (EOFException) JavaClassName() string {
-	return "java.io.EOFException"
+func (ZipException) JavaClassName() string {
+	return "java.util.zip.ZipException"
 }
diff --git a/java_exception/EOF_exception.go b/java_exception/zone_rules_exception.go
similarity index 62%
copy from java_exception/EOF_exception.go
copy to java_exception/zone_rules_exception.go
index 214454f..072f7a7 100644
--- a/java_exception/EOF_exception.go
+++ b/java_exception/zone_rules_exception.go
@@ -1,4 +1,4 @@
-// Copyright 2016-2019 summerbuger@gmail.com
+// Copyright 2016-2019 Yincheng Fang
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
 
 package java_exception
 
-type EOFException struct {
+type ZoneRulesException struct {
 	SerialVersionUID     int64
 	DetailMessage        string
+	SuppressedExceptions []Throwabler
 	StackTrace           []StackTraceElement
-	SuppressedExceptions []EOFException
-	Cause                *EOFException
+	Cause                Throwabler
 }
 
-func NewEOFException(detailMessage string) *EOFException {
-	return &EOFException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
+func NewZoneRulesException(detailMessage string) *ZoneRulesException {
+	return &ZoneRulesException{DetailMessage: detailMessage, StackTrace: []StackTraceElement{}}
 }
 
-func (e EOFException) Error() string {
+func (e ZoneRulesException) Error() string {
 	return e.DetailMessage
 }
 
-func (EOFException) JavaClassName() string {
-	return "java.io.EOFException"
+func (ZoneRulesException) JavaClassName() string {
+	return "java.time.zone.ZoneRulesException"
 }
diff --git a/java_exception_test.go b/java_exception_test.go
index 235014e..bf5b06e 100644
--- a/java_exception_test.go
+++ b/java_exception_test.go
@@ -35,6 +35,11 @@
 	doTestException(t, "throw_illegalMonitorStateException", "illegalMonitorStateException")
 	doTestException(t, "throw_illegalStateException", "illegalStateException")
 	doTestException(t, "throw_IOException", "IOException")
+	doTestException(t, "throw_CloneNotSupportedException", "CloneNotSupportedException")
+	doTestException(t, "throw_InterruptedException", "InterruptedException")
+	doTestException(t, "throw_InterruptedIOException", "InterruptedIOException")
+	doTestException(t, "throw_LambdaConversionException", "LambdaConversionException")
+	doTestException(t, "throw_UnmodifiableClassException", "UnmodifiableClassException")
 	doTestException(t, "throw_NullPointerException", "nullPointerException")
 	doTestException(t, "throw_UncheckedIOException", "uncheckedIOException")
 	doTestException(t, "throw_FileNotFoundException", "fileNotFoundException")
@@ -66,10 +71,46 @@
 	doTestException(t, "throw_EmptyStackException", "EmptyStackException")
 	doTestException(t, "throw_IllformedLocaleException", "IllformedLocaleException")
 	doTestException(t, "throw_NoSuchElementException", "NoSuchElementException")
+	doTestException(t, "throw_NegativeArraySizeException", "NegativeArraySizeException")
+	doTestException(t, "throw_UnsupportedOperationException", "UnsupportedOperationException")
+	doTestException(t, "throw_ArithmeticException", "ArithmeticException")
+	doTestException(t, "throw_InputMismatchException", "InputMismatchException")
+	doTestException(t, "throw_ExecutionException", "ExecutionException")
+	doTestException(t, "throw_InvalidPreferencesFormatException", "InvalidPreferencesFormatException")
+	doTestException(t, "throw_TimeoutException", "TimeoutException")
+	doTestException(t, "throw_BackingStoreException", "BackingStoreException")
+	doTestException(t, "throw_DataFormatException", "DataFormatException")
+	doTestException(t, "throw_BrokenBarrierException", "BrokenBarrierException")
+	doTestException(t, "throw_TooManyListenersException", "TooManyListenersException")
+	doTestException(t, "throw_InvalidPropertiesFormatException", "InvalidPropertiesFormatException")
+	doTestException(t, "throw_ZipException", "ZipException")
+	doTestException(t, "throw_JarException", "JarException")
+	doTestException(t, "throw_IllegalClassFormatException", "IllegalClassFormatException")
+	doTestException(t, "throw_ReflectiveOperationException", "ReflectiveOperationException")
+	doTestException(t, "throw_InvocationTargetException", "InvocationTargetException")
+	doTestException(t, "throw_NoSuchMethodException", "NoSuchMethodException")
+	doTestException(t, "throw_NoSuchFieldException", "NoSuchFieldException")
+	doTestException(t, "throw_IllegalAccessException", "IllegalAccessException")
+	doTestException(t, "throw_ClassNotFoundException", "ClassNotFoundException")
+	doTestException(t, "throw_InstantiationException", "InstantiationException")
+	doTestException(t, "throw_DateTimeException", "DateTimeException")
+	doTestException(t, "throw_UnsupportedTemporalTypeException", "UnsupportedTemporalTypeException")
+	doTestException(t, "throw_ZoneRulesException", "ZoneRulesException")
+	doTestException(t, "throw_DateTimeParseException", "DateTimeParseException")
+	doTestException(t, "throw_FormatterClosedException", "null")
+	doTestException(t, "throw_CancellationException", "CancellationException")
+	doTestException(t, "throw_UnknownFormatConversionException", "Conversion = 'UnknownFormatConversionException'")
+	doTestException(t, "throw_UnknownFormatFlagsException", "Flags = UnknownFormatFlagsException")
+	doTestException(t, "throw_IllegalFormatFlagsException", "Flags = 'IllegalFormatFlagsException'")
+	doTestException(t, "throw_IllegalFormatPrecisionException", "1")
+	doTestException(t, "throw_IllegalFormatCodePointException", "Code point = 0x1")
+	doTestException(t, "throw_MissingFormatArgumentException", "Format specifier 'MissingFormatArgumentException'")
+	doTestException(t, "throw_MissingFormatWidthException", "MissingFormatWidthException")
 }
 
 func doTestException(t *testing.T, method, content string) {
 	testDecodeFrameworkFunc(t, method, func(r interface{}) {
+		t.Logf("%#v", r)
 		assert.Equal(t, content, r.(error).Error())
 	})
 }
diff --git a/list.go b/list.go
index c55ef5e..4a1093f 100644
--- a/list.go
+++ b/list.go
@@ -17,24 +17,165 @@
 import (
 	"io"
 	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
 )
 
 import (
 	perrors "github.com/pkg/errors"
 )
 
+var (
+	listTypeNameMapper = &sync.Map{}
+	listTypeMapper     = map[string]reflect.Type{
+		"string":           reflect.TypeOf(""),
+		"java.lang.String": reflect.TypeOf(""),
+		"char":             reflect.TypeOf(""),
+		"short":            reflect.TypeOf(int32(0)),
+		"int":              reflect.TypeOf(int32(0)),
+		"long":             reflect.TypeOf(int64(0)),
+		"float":            reflect.TypeOf(float64(0)),
+		"double":           reflect.TypeOf(float64(0)),
+		"boolean":          reflect.TypeOf(true),
+		"java.util.Date":   reflect.TypeOf(time.Time{}),
+		"date":             reflect.TypeOf(time.Time{}),
+		"object":           reflect.TypeOf([]Object{}).Elem(),
+		"java.lang.Object": reflect.TypeOf([]Object{}).Elem(),
+	}
+)
+
+func init() {
+	listTypeNameMapper.Store("string", "[string")
+	listTypeNameMapper.Store("int8", "[short")
+	listTypeNameMapper.Store("int16", "[short")
+	listTypeNameMapper.Store("uint16", "[short")
+	listTypeNameMapper.Store("int32", "[int")
+	listTypeNameMapper.Store("uint32", "[int")
+	listTypeNameMapper.Store("int", "[long")
+	listTypeNameMapper.Store("uint", "[long")
+	listTypeNameMapper.Store("int64", "[long")
+	listTypeNameMapper.Store("uint64", "[long")
+	listTypeNameMapper.Store("float32", "[float")
+	listTypeNameMapper.Store("float64", "[double")
+	listTypeNameMapper.Store("bool", "[boolean")
+	listTypeNameMapper.Store("time.Time", "[date")
+	listTypeNameMapper.Store("java_exception.Throwabler", "[java.lang.Throwable")
+
+	listTypeNameMapper.Store("hessian.Object", "[object")
+}
+
+func registerTypeName(gotype, javatype string) {
+	listTypeNameMapper.Store(gotype, "["+javatype)
+}
+
+func getListTypeName(gotype string) string {
+	buf := strings.Builder{}
+	count := strings.Count(gotype, "[]")
+	for i := 0; i < count; i++ {
+		buf.WriteString("[")
+	}
+	gotype = strings.Replace(gotype, "[]", "", -1)
+	v, ok := listTypeNameMapper.Load(strings.TrimPrefix(gotype, "*"))
+	if ok {
+		buf.WriteString(v.(string))
+		return buf.String()
+	}
+	return ""
+}
+
+func getListType(javalistname string) reflect.Type {
+	javaname := javalistname
+	if strings.Index(javaname, "[") == 0 {
+		javaname = javaname[1:]
+	}
+	if strings.Index(javaname, "[") == 0 {
+		lt := getListType(javaname)
+		if lt == nil {
+			return nil
+		}
+		return reflect.SliceOf(lt)
+	}
+
+	var sliceTy reflect.Type
+	ltm := listTypeMapper[javaname]
+	if ltm != nil {
+		sliceTy = reflect.SliceOf(ltm)
+	}
+
+	if sliceTy == nil {
+		tpStructInfo, _ := getStructInfo(javaname)
+		tp := tpStructInfo.typ
+		if tp == nil {
+			return nil
+		}
+		if tp.Kind() != reflect.Ptr {
+			tp = reflect.New(tp).Type()
+		}
+		sliceTy = reflect.SliceOf(tp)
+	}
+	return sliceTy
+}
+
+// Object is equal to Object of java When encoding
+type Object interface{}
+
 /////////////////////////////////////////
 // List
 /////////////////////////////////////////
 
-// # list/vector
+// encList write list
+func (e *Encoder) encList(v interface{}) error {
+	if !strings.Contains(reflect.TypeOf(v).String(), "interface {}") {
+		return e.writeTypedList(v)
+	}
+	return e.writeUntypedList(v)
+}
+
+// writeTypedList write typed list
+// Include 3 formats:
 // ::= x55 type value* 'Z'   # variable-length list
 // ::= 'V' type int value*   # fixed-length list
+// ::= [x70-77] type value*  # fixed-length typed list
+func (e *Encoder) writeTypedList(v interface{}) error {
+	var (
+		err error
+	)
+
+	value := reflect.ValueOf(v)
+
+	// check ref
+	if n, ok := e.checkRefMap(value); ok {
+		e.buffer = encRef(e.buffer, n)
+		return nil
+	}
+
+	value = UnpackPtrValue(value)
+	totype := UnpackPtrType(value.Type().Elem()).String()
+	var typeName = getListTypeName(totype)
+	if typeName == "" {
+		return perrors.New("no this type name: " + totype)
+	}
+
+	e.buffer = encByte(e.buffer, BC_LIST_FIXED) // 'V'
+	e.buffer = encString(e.buffer, typeName)
+	e.buffer = encInt32(e.buffer, int32(value.Len()))
+	for i := 0; i < value.Len(); i++ {
+		if err = e.Encode(value.Index(i).Interface()); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// writeUntypedList write untyped list
+// Include 3 formats:
 // ::= x57 value* 'Z'        # variable-length untyped list
 // ::= x58 int value*        # fixed-length untyped list
-// ::= [x70-77] type value*  # fixed-length typed list
 // ::= [x78-7f] value*       # fixed-length untyped list
-func (e *Encoder) encUntypedList(v interface{}) error {
+func (e *Encoder) writeUntypedList(v interface{}) error {
 	var (
 		err error
 	)
@@ -173,10 +314,25 @@
 		return nil, nil
 	}
 
-	arr := make([]interface{}, length)
-	aryValue := reflect.ValueOf(arr)
-	holder := d.appendRefs(aryValue)
+	var (
+		aryValue reflect.Value
+		arrType  reflect.Type
+	)
+	t, err := strconv.Atoi(listTyp)
+	if err == nil {
+		arrType = d.typeRefs.Get(t)
+	} else {
+		arrType = getListType(listTyp)
+	}
 
+	if arrType != nil {
+		aryValue = reflect.MakeSlice(arrType, length, length)
+		d.typeRefs.appendTypeRefs(arrType.String(), arrType)
+	} else {
+		aryValue = reflect.ValueOf(make([]interface{}, length, length))
+		d.typeRefs.appendTypeRefs(strings.Replace(listTyp, "[", "", -1), aryValue.Type())
+	}
+	holder := d.appendRefs(aryValue)
 	for j := 0; j < length || isVariableArr; j++ {
 		it, err := d.DecodeValue()
 		if err != nil {
@@ -190,11 +346,15 @@
 			if it != nil {
 				aryValue = reflect.Append(aryValue, EnsureRawValue(it))
 			} else {
-				aryValue = reflect.Append(aryValue, NilValue)
+				aryValue = reflect.Append(aryValue, reflect.Zero(aryValue.Type().Elem()))
 			}
 			holder.change(aryValue)
 		} else {
-			arr[j] = it
+			if it != nil {
+				aryValue.Index(j).Set(EnsureRawValue(it))
+			} else {
+				SetValue(aryValue.Index(j), EnsureRawValue(it))
+			}
 		}
 	}
 
@@ -241,7 +401,7 @@
 			if it != nil {
 				aryValue = reflect.Append(aryValue, EnsureRawValue(it))
 			} else {
-				aryValue = reflect.Append(aryValue, NilValue)
+				aryValue = reflect.Append(aryValue, reflect.Zero(aryValue.Type().Elem()))
 			}
 			holder.change(aryValue)
 		} else {
diff --git a/list_test.go b/list_test.go
index 1832c8e..d28fc76 100644
--- a/list_test.go
+++ b/list_test.go
@@ -15,7 +15,14 @@
 package hessian
 
 import (
+	"fmt"
+	"reflect"
 	"testing"
+	"time"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
 )
 
 func TestEncList(t *testing.T) {
@@ -30,41 +37,154 @@
 	e = NewEncoder()
 	list = []interface{}{100, 10.001, "hello", []byte{0, 2, 4, 6, 8, 10}, true, nil, false}
 	e.Encode(list)
-	if len(e.Buffer()) == 0 {
-		t.Fail()
-	}
+	assert.NotEqual(t, 0, len(e.Buffer()))
 
 	d = NewDecoder(e.Buffer())
 	res, err = d.Decode()
-	if err != nil {
-		t.Errorf("Decode() = %+v", err)
-	}
-	t.Logf("decode(%v) = %v, %v\n", list, res, err)
+	assert.NoError(t, err)
+	assert.Equal(t, fmt.Sprintf("%v", list), fmt.Sprintf("%v", res))
+
+	// typed list - int32
+	e = NewEncoder()
+	list_1 := []int32{1, 2, 3}
+	e.Encode(list_1)
+	assert.NotEqual(t, 0, len(e.Buffer()))
+
+	d = NewDecoder(e.Buffer())
+	res, err = d.Decode()
+	assert.NoError(t, err)
+	assert.True(t, reflect.DeepEqual(res, list_1))
+
+	// typed list - [][][]int32
+	e = NewEncoder()
+	list_2 := [][][]int32{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}}
+	e.Encode(list_2)
+	assert.NotEqual(t, 0, len(e.Buffer()))
+
+	d = NewDecoder(e.Buffer())
+	res, err = d.Decode()
+	assert.NoError(t, err)
+	assert.True(t, reflect.DeepEqual(res, list_2))
+
 }
 
 func TestList(t *testing.T) {
-	RegisterPOJOs(new(A0), new(A1))
+	RegisterPOJOs(new(A0), new(A1), new(TypedListTest))
 
-	testDecodeFramework(t, "replyTypedFixedList_0", []interface{}{})
-	testDecodeFramework(t, "replyTypedFixedList_1", []interface{}{"1"})
-	testDecodeFramework(t, "replyTypedFixedList_7", []interface{}{"1", "2", "3", "4", "5", "6", "7"})
-	testDecodeFramework(t, "replyTypedFixedList_8", []interface{}{"1", "2", "3", "4", "5", "6", "7", "8"})
+	testDecodeFramework(t, "replyTypedFixedList_0", []string{})
+	testDecodeFramework(t, "replyTypedFixedList_1", []string{"1"})
+	testDecodeFramework(t, "replyTypedFixedList_7", []string{"1", "2", "3", "4", "5", "6", "7"})
+	testDecodeFramework(t, "replyTypedFixedList_8", []string{"1", "2", "3", "4", "5", "6", "7", "8"})
 	testDecodeFramework(t, "replyUntypedFixedList_0", []interface{}{})
 	testDecodeFramework(t, "replyUntypedFixedList_1", []interface{}{"1"})
 	testDecodeFramework(t, "replyUntypedFixedList_7", []interface{}{"1", "2", "3", "4", "5", "6", "7"})
 	testDecodeFramework(t, "replyUntypedFixedList_8", []interface{}{"1", "2", "3", "4", "5", "6", "7", "8"})
 
-	testDecodeFramework(t, "customReplyTypedFixedListHasNull", []interface{}{new(A0), new(A1), nil})
-	testDecodeFramework(t, "customReplyTypedVariableListHasNull", []interface{}{new(A0), new(A1), nil})
+	testDecodeFramework(t, "customReplyTypedFixedListHasNull", []Object{new(A0), new(A1), nil})
+	testDecodeFramework(t, "customReplyTypedVariableListHasNull", []Object{new(A0), new(A1), nil})
 	testDecodeFramework(t, "customReplyUntypedFixedListHasNull", []interface{}{new(A0), new(A1), nil})
 	testDecodeFramework(t, "customReplyUntypedVariableListHasNull", []interface{}{new(A0), new(A1), nil})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_A0", []*A0{new(A0), new(A0), nil})
+	testDecodeFramework(t, "customReplyTypedVariableList_A0", []*A0{new(A0), new(A0), nil})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_int", []int32{1, 2, 3})
+	testDecodeFramework(t, "customReplyTypedVariableList_int", []int32{1, 2, 3})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_long", []int64{1, 2, 3})
+	testDecodeFramework(t, "customReplyTypedVariableList_long", []int64{1, 2, 3})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_float", []float64{1, 2, 3})
+	testDecodeFramework(t, "customReplyTypedVariableList_float", []float64{1, 2, 3})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_double", []float64{1, 2, 3})
+	testDecodeFramework(t, "customReplyTypedVariableList_double", []float64{1, 2, 3})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_short", []int32{1, 2, 3})
+	testDecodeFramework(t, "customReplyTypedVariableList_short", []int32{1, 2, 3})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_char", []string{"1", "2", "3"})
+	testDecodeFramework(t, "customReplyTypedVariableList_char", []string{"1", "2", "3"})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_boolean", []bool{true, false, true})
+	testDecodeFramework(t, "customReplyTypedVariableList_boolean", []bool{true, false, true})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_date", []time.Time{time.Unix(1560864, 0),
+		time.Unix(1560864, 0), time.Unix(1560864, 0)})
+	testDecodeFramework(t, "customReplyTypedVariableList_date", []time.Time{time.Unix(1560864, 0),
+		time.Unix(1560864, 0), time.Unix(1560864, 0)})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_arrays", [][][]int32{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}})
+	testDecodeFramework(t, "customReplyTypedFixedList_A0arrays", [][][]*A0{{{new(A0), new(A0), new(A0)}, {new(A0), new(A0), new(A0), nil}},
+		{{new(A0)}, {new(A0)}}})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_Test", &TypedListTest{A: &A0{}, List: [][]*A0{{new(A0), new(A0)}, {new(A0), new(A0)}}, List1: [][]*A1{{new(A1), new(A1)}, {new(A1), new(A1)}}})
+
+	testDecodeFramework(t, "customReplyTypedFixedList_Object", []Object{new(A0)})
 }
 
 func TestListEncode(t *testing.T) {
+	RegisterPOJOs(new(A0))
+
 	testJavaDecode(t, "argUntypedFixedList_0", []interface{}{})
 	testJavaDecode(t, "argUntypedFixedList_1", []interface{}{"1"})
 	testJavaDecode(t, "argUntypedFixedList_7", []interface{}{"1", "2", "3", "4", "5", "6", "7"})
 	testJavaDecode(t, "argUntypedFixedList_8", []interface{}{"1", "2", "3", "4", "5", "6", "7", "8"})
 
 	testJavaDecode(t, "customArgUntypedFixedListHasNull", []interface{}{new(A0), new(A1), nil})
+
+	testJavaDecode(t, "customArgTypedFixedList", []*A0{new(A0)})
+
+	testJavaDecode(t, "argTypedFixedList_0", []string{})
+	testJavaDecode(t, "argTypedFixedList_7", []string{"1", "2", "3", "4", "5", "6", "7"})
+
+	testJavaDecode(t, "customArgTypedFixedList_short_0", []int8{})
+	testJavaDecode(t, "customArgTypedFixedList_short_7", []int8{1, 2, 3, 4, 5, 6, 7})
+	testJavaDecode(t, "customArgTypedFixedList_short_0", []int16{})
+	testJavaDecode(t, "customArgTypedFixedList_short_7", []int16{1, 2, 3, 4, 5, 6, 7})
+	testJavaDecode(t, "customArgTypedFixedList_short_0", []uint16{})
+	testJavaDecode(t, "customArgTypedFixedList_short_7", []uint16{1, 2, 3, 4, 5, 6, 7})
+
+	testJavaDecode(t, "customArgTypedFixedList_int_0", []int32{})
+	testJavaDecode(t, "customArgTypedFixedList_int_7", []uint32{1, 2, 3, 4, 5, 6, 7})
+
+	testJavaDecode(t, "customArgTypedFixedList_long_0", []int{})
+	testJavaDecode(t, "customArgTypedFixedList_long_7", []int{1, 2, 3, 4, 5, 6, 7})
+	testJavaDecode(t, "customArgTypedFixedList_long_0", []uint{})
+	testJavaDecode(t, "customArgTypedFixedList_long_7", []uint{1, 2, 3, 4, 5, 6, 7})
+	testJavaDecode(t, "customArgTypedFixedList_long_0", []int64{})
+	testJavaDecode(t, "customArgTypedFixedList_long_7", []int64{1, 2, 3, 4, 5, 6, 7})
+	testJavaDecode(t, "customArgTypedFixedList_long_0", []uint64{})
+	testJavaDecode(t, "customArgTypedFixedList_long_7", []uint64{1, 2, 3, 4, 5, 6, 7})
+
+	testJavaDecode(t, "customArgTypedFixedList_float_0", []float32{})
+	testJavaDecode(t, "customArgTypedFixedList_float_7", []float32{1, 2, 3, 4, 5, 6, 7})
+
+	testJavaDecode(t, "customArgTypedFixedList_double_0", []float64{})
+	testJavaDecode(t, "customArgTypedFixedList_double_7", []float64{1, 2, 3, 4, 5, 6, 7})
+
+	testJavaDecode(t, "customArgTypedFixedList_boolean_0", []bool{})
+	testJavaDecode(t, "customArgTypedFixedList_boolean_7", []bool{true, false, true, false, true, false, true})
+
+	testJavaDecode(t, "customArgTypedFixedList_date_0", []time.Time{})
+	testJavaDecode(t, "customArgTypedFixedList_date_3", []time.Time{time.Unix(1560864, 0),
+		time.Unix(1560864, 0), time.Unix(1560864, 0)})
+
+	testJavaDecode(t, "customArgTypedFixedList_arrays", [][][]int32{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}})
+	testJavaDecode(t, "customArgTypedFixedList_A0arrays", [][][]*A0{{{new(A0), new(A0), new(A0)}, {new(A0), new(A0), new(A0), nil}},
+		{{new(A0)}, {new(A0)}}})
+
+	testJavaDecode(t, "customArgTypedFixedList_Test", &TypedListTest{A: new(A0), List: [][]*A0{{new(A0), new(A0)}, {new(A0), new(A0)}}, List1: [][]*A1{{new(A1), new(A1)}, {new(A1), new(A1)}}})
+
+	testJavaDecode(t, "customArgTypedFixedList_Object", []Object{new(A0)})
+}
+
+type TypedListTest struct {
+	A     *A0
+	List  [][]*A0
+	List1 [][]*A1
+}
+
+func (*TypedListTest) JavaClassName() string {
+	return "test.TypedListTest"
 }
diff --git a/object.go b/object.go
index b653f6b..d9f3cc0 100644
--- a/object.go
+++ b/object.go
@@ -419,7 +419,7 @@
 			if err != nil {
 				return nil, err
 			}
-		case reflect.Struct:
+		case reflect.Struct, reflect.Interface:
 			var (
 				err error
 				s   interface{}
@@ -442,7 +442,7 @@
 			}
 
 		default:
-			return nil, perrors.Errorf("unknown struct member type: %v", kind)
+			return nil, perrors.Errorf("unknown struct member type: %v %v", kind, typ.Name()+"."+typ.Field(index).Name)
 		}
 	} // end for
 
@@ -522,7 +522,9 @@
 		cls, _ = clsDef.(classInfo)
 		//add to slice
 		d.appendClsDef(cls)
-
+		if c, ok := GetSerializer(cls.javaName); ok {
+			return c.DecObject(d)
+		}
 		return d.DecodeValue()
 
 	case tag == BC_OBJECT:
diff --git a/pojo.go b/pojo.go
index 1494b33..de9dc16 100644
--- a/pojo.go
+++ b/pojo.go
@@ -144,6 +144,7 @@
 	structInfo.javaName = o.JavaClassName()
 	structInfo.inst = o
 	pojoRegistry.j2g[structInfo.javaName] = structInfo.goName
+	registerTypeName(structInfo.goName, structInfo.javaName)
 
 	// prepare fields info of objectDef
 	for i := 0; i < structInfo.typ.NumField(); i++ {
@@ -295,7 +296,10 @@
 		return nil, cls, perrors.Errorf("illegal class index @idx %d", idx)
 	}
 	cls = pojoRegistry.classInfoList[idx]
-	clsName = pojoRegistry.j2g[cls.javaName]
+	clsName, ok = pojoRegistry.j2g[cls.javaName]
+	if !ok {
+		return nil, cls, perrors.Errorf("can not find java type name %s in registry", cls.javaName)
+	}
 	s, ok = pojoRegistry.registry[clsName]
 	if !ok {
 		return nil, cls, perrors.Errorf("can not find go type name %s in registry", clsName)
diff --git a/request.go b/request.go
index 032fc50..58cc051 100644
--- a/request.go
+++ b/request.go
@@ -42,32 +42,56 @@
 		return "V"
 	case bool:
 		return "Z"
+	case []bool:
+		return "[Z"
 	case byte:
 		return "B"
+	case []byte:
+		return "[B"
 	case int8:
 		return "B"
+	case []int8:
+		return "[B"
 	case int16:
 		return "S"
+	case []int16:
+		return "[S"
 	case uint16: // Equivalent to Char of Java
 		return "C"
+	case []uint16:
+		return "[C"
 	// case rune:
 	//	return "C"
 	case int:
-		return "I"
+		return "J"
+	case []int:
+		return "[J"
 	case int32:
 		return "I"
+	case []int32:
+		return "[I"
 	case int64:
 		return "J"
+	case []int64:
+		return "[J"
 	case time.Time:
 		return "java.util.Date"
+	case []time.Time:
+		return "[Ljava.util.Date"
 	case float32:
 		return "F"
+	case []float32:
+		return "[F"
 	case float64:
 		return "D"
+	case []float64:
+		return "[D"
 	case string:
 		return "java.lang.String"
-	case []byte:
-		return "[B"
+	case []string:
+		return "[Ljava.lang.String;"
+	case []Object:
+		return "[Ljava.lang.Object;"
 	case map[interface{}]interface{}:
 		// return  "java.util.HashMap"
 		return "java.util.Map"
@@ -82,6 +106,9 @@
 		case reflect.Struct:
 			return "java.lang.Object"
 		case reflect.Slice, reflect.Array:
+			if t.Elem().Kind() == reflect.Struct {
+				return "[Ljava.lang.Object;"
+			}
 			// return "java.util.ArrayList"
 			return "java.util.List"
 		case reflect.Map: // Enter here, map may be map[string]int
@@ -108,6 +135,8 @@
 		}
 		if !strings.Contains(typ, ".") {
 			types += typ
+		} else if strings.Index(typ, "[") == 0 {
+			types += strings.Replace(typ, ".", "/", -1)
 		} else {
 			// java.util.List -> Ljava/util/List;
 			types += "L" + strings.Replace(typ, ".", "/", -1) + ";"
@@ -170,7 +199,7 @@
 
 	// dubbo version + path + version + method
 	encoder.Encode(DUBBO_VERSION)
-	encoder.Encode(service.Target)
+	encoder.Encode(service.Path)
 	encoder.Encode(service.Version)
 	encoder.Encode(service.Method)
 
@@ -185,6 +214,7 @@
 
 	serviceParams = make(map[string]string)
 	serviceParams[PATH_KEY] = service.Path
+	serviceParams[GROUP_KEY] = service.Group
 	serviceParams[INTERFACE_KEY] = service.Interface
 	if len(version) != 0 {
 		serviceParams[VERSION_KEY] = version
diff --git a/request_test.go b/request_test.go
index 7fc067a..9db7c56 100644
--- a/request_test.go
+++ b/request_test.go
@@ -25,10 +25,9 @@
 
 func TestPackRequest(t *testing.T) {
 	bytes, err := packRequest(Service{
-		Path:      "/test",
+		Path:      "test",
 		Interface: "ITest",
 		Version:   "v1.0",
-		Target:    "test",
 		Method:    "test",
 		Timeout:   time.Second * 10,
 	}, DubboHeader{
@@ -44,6 +43,13 @@
 	}
 }
 
+func TestGetArgsTypeList(t *testing.T) {
+	type Test struct{}
+	str, err := getArgsTypeList([]interface{}{nil, 1, []int{2}, true, []bool{false}, "a", []string{"b"}, Test{}, &Test{}, []Test{}, map[string]Test{}})
+	assert.NoError(t, err)
+	assert.Equal(t, "VJ[JZ[ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Map;", str)
+}
+
 func TestDescRegex(t *testing.T) {
 	results := DescRegex.FindAllString("Ljava/lang/String;", -1)
 	assert.Equal(t, 1, len(results))
diff --git a/response.go b/response.go
index 6918699..da9bb34 100644
--- a/response.go
+++ b/response.go
@@ -85,7 +85,7 @@
 
 			if e, ok := ret.(error); ok { // throw error
 				encoder.Encode(resWithException)
-				if t, ok := e.(Throwabler); ok {
+				if t, ok := e.(java_exception.Throwabler); ok {
 					encoder.Encode(t)
 				} else {
 					encoder.Encode(java_exception.NewThrowable(e.Error()))
@@ -246,6 +246,12 @@
 	inValue := EnsurePackValue(in)
 	outValue := EnsurePackValue(out)
 
+	outType := outValue.Type().String()
+	if outType == "interface {}" || outType == "*interface {}" {
+		SetValue(outValue, inValue)
+		return nil
+	}
+
 	switch inValue.Type().Kind() {
 	case reflect.Slice, reflect.Array:
 		return CopySlice(inValue, outValue)
diff --git a/response_test.go b/response_test.go
index 31c2b6c..b88cbcd 100644
--- a/response_test.go
+++ b/response_test.go
@@ -95,6 +95,17 @@
 	s3 := []interface{}{rr{"dubbo", 666}, 123, "hello"}
 	var s3r []interface{}
 	doTestReflectResponse(t, s3, &s3r)
+
+	// ------ interface test -------
+	in1 := []interface{}{rr{"dubbo", 666}, 123, "hello"}
+	var inr1 *interface{}
+	doTestReflectResponse(t, in1, reflect.New(reflect.TypeOf(inr1).Elem()).Interface())
+
+	in2 := make(map[string]rr)
+	var inr2 map[string]rr
+	m3["dubbo"] = rr{"hello", 123}
+	m3["go"] = rr{"world", 456}
+	doTestReflectResponse(t, in2, &inr2)
 }
 
 // separately test copy normal map to map[interface{}]interface{}
diff --git a/serialize.go b/serialize.go
new file mode 100644
index 0000000..510f967
--- /dev/null
+++ b/serialize.go
@@ -0,0 +1,67 @@
+// Copyright 2016-2019 aliiohs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hessian
+
+import (
+	big "github.com/dubbogo/gost/math/big"
+)
+
+func init() {
+	RegisterPOJO(&big.Decimal{})
+	SetSerializer("java.math.BigDecimal", DecimalSerializer{})
+}
+
+type Serializer interface {
+	EncObject(*Encoder, POJO) error
+	DecObject(*Decoder) (interface{}, error)
+}
+
+var serializerMap = make(map[string]Serializer, 16)
+
+func SetSerializer(key string, codec Serializer) {
+	serializerMap[key] = codec
+}
+
+func GetSerializer(key string) (Serializer, bool) {
+	codec, ok := serializerMap[key]
+	return codec, ok
+}
+
+type DecimalSerializer struct{}
+
+func (DecimalSerializer) EncObject(e *Encoder, v POJO) error {
+	decimal, ok := v.(big.Decimal)
+	if !ok {
+		return e.encObject(v)
+	}
+	decimal.Value = decimal.String()
+	return e.encObject(decimal)
+}
+
+func (DecimalSerializer) DecObject(d *Decoder) (interface{}, error) {
+	dec, err := d.DecodeValue()
+	if err != nil {
+		return nil, err
+	}
+	result, ok := dec.(*big.Decimal)
+	if !ok {
+		panic("result type is not decimal,please check the whether the conversion is ok")
+	}
+	err = result.FromString(result.Value)
+	if err != nil {
+		return nil, err
+	}
+	return result, nil
+}
diff --git a/serialize_test.go b/serialize_test.go
new file mode 100644
index 0000000..195a758
--- /dev/null
+++ b/serialize_test.go
@@ -0,0 +1,68 @@
+// Copyright 2016-2019 aliiohs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hessian
+
+import (
+	"reflect"
+	"testing"
+)
+
+import (
+	big "github.com/dubbogo/gost/math/big"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestEncodeDecodeDecimal(t *testing.T) {
+	var dec big.Decimal
+	_ = dec.FromString("100.256")
+	e := NewEncoder()
+	err := e.Encode(dec)
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	d := NewDecoder(e.buffer)
+	decObj, err := d.Decode()
+	if err != nil {
+		t.Error(err)
+		t.FailNow()
+	}
+
+	if !reflect.DeepEqual(dec.String(), decObj.(*big.Decimal).String()) {
+		t.Errorf("expect: %v, but get: %v", dec, decObj)
+	}
+}
+
+func TestDecimalGoDecode(t *testing.T) {
+	var d big.Decimal
+	_ = d.FromString("100.256")
+	d.Value = d.String()
+	doTestDecimal(t, "customReplyTypedFixedDecimal", "100.256")
+}
+
+func TestDecimalJavaDecode(t *testing.T) {
+	var d big.Decimal
+	_ = d.FromString("100.256")
+	d.Value = d.String()
+	testJavaDecode(t, "customArgTypedFixedList_Decimal", d)
+}
+
+func doTestDecimal(t *testing.T, method, content string) {
+	testDecodeFrameworkFunc(t, method, func(r interface{}) {
+		t.Logf("%#v", r)
+		assert.Equal(t, content, r.(*big.Decimal).String())
+	})
+}
diff --git a/test_hessian/src/main/java/test/TestCustomDecode.java b/test_hessian/src/main/java/test/TestCustomDecode.java
index 05413f0..27ac4ce 100644
--- a/test_hessian/src/main/java/test/TestCustomDecode.java
+++ b/test_hessian/src/main/java/test/TestCustomDecode.java
@@ -1,43 +1,171 @@
-// Copyright 2019 Xinge Gao

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//     http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-

-package test;

-

-import com.caucho.hessian.io.Hessian2Input;

-import com.caucho.hessian.test.A0;

-import com.caucho.hessian.test.A1;

-

-import java.io.InputStream;

-import java.util.ArrayList;

-import java.util.List;

-

-

-public class TestCustomDecode {

-

-    private Hessian2Input input;

-

-    TestCustomDecode(InputStream is) {

-        input = new Hessian2Input(is);

-    }

-

-    public Object customArgUntypedFixedListHasNull() throws Exception {

-        List list = new ArrayList();

-        list.add(new A0());

-        list.add(new A1());

-        list.add(null);

-

-        Object o = input.readObject();

-        return list.equals(o);

-    }

+// Copyright 2019 Xinge Gao
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test;
+
+import com.caucho.hessian.io.Hessian2Input;
+import com.caucho.hessian.test.A0;
+import com.caucho.hessian.test.A1;
+
+import javax.xml.crypto.Data;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.math.BigDecimal;
+
+public class TestCustomDecode {
+
+    private Hessian2Input input;
+
+    TestCustomDecode(InputStream is) {
+        input = new Hessian2Input(is);
+    }
+
+    public Object customArgUntypedFixedListHasNull() throws Exception {
+        List list = new ArrayList();
+        list.add(new A0());
+        list.add(new A1());
+        list.add(null);
+
+        Object o = input.readObject();
+        return list.equals(o);
+    }
+
+    public Object customArgTypedFixedList() throws Exception {
+        A0[] list = new A0[]{new A0()};
+        Object o = input.readObject();
+        return Arrays.equals(list,(A0[])o);
+    }
+
+    public Object customArgTypedFixedList_short_0() throws Exception {
+        short[] list = new short[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(short[])o);
+    }
+
+    public Object customArgTypedFixedList_short_7() throws Exception {
+        short[] list = new short[]{1,2,3,4,5,6,7};
+        Object o = input.readObject();
+        return Arrays.equals(list,(short[])o);
+    }
+
+    public Object customArgTypedFixedList_int_0() throws Exception {
+        int[] list = new int[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(int[])o);
+    }
+
+    public Object customArgTypedFixedList_int_7() throws Exception {
+        int[] list = new int[]{1,2,3,4,5,6,7};
+        Object o = input.readObject();
+        return Arrays.equals(list,(int[])o);
+    }
+
+    public Object customArgTypedFixedList_long_0() throws Exception {
+        long[] list = new long[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(long[])o);
+    }
+
+    public Object customArgTypedFixedList_long_7() throws Exception {
+        long[] list = new long[]{1,2,3,4,5,6,7};
+        Object o = input.readObject();
+        return Arrays.equals(list,(long[])o);
+    }
+
+    public Object customArgTypedFixedList_float_0() throws Exception {
+        float[] list = new float[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(float[])o);
+    }
+
+    public Object customArgTypedFixedList_float_7() throws Exception {
+        float[] list = new float[]{1,2,3,4,5,6,7};
+        Object o = input.readObject();
+        return Arrays.equals(list,(float[])o);
+    }
+
+    public Object customArgTypedFixedList_double_0() throws Exception {
+        double[] list = new double[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(double[])o);
+    }
+
+    public Object customArgTypedFixedList_double_7() throws Exception {
+        double[] list = new double[]{1,2,3,4,5,6,7};
+        Object o = input.readObject();
+        return Arrays.equals(list,(double[])o);
+    }
+
+    public Object customArgTypedFixedList_boolean_0() throws Exception {
+        boolean[] list = new boolean[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(boolean[])o);
+    }
+
+    public Object customArgTypedFixedList_boolean_7() throws Exception {
+        boolean[] list = new boolean[]{true,false,true,false,true,false,true};
+        Object o = input.readObject();
+        return Arrays.equals(list,(boolean[])o);
+    }
+
+    public Object customArgTypedFixedList_date_0() throws Exception {
+        Date[] list = new Date[]{};
+        Object o = input.readObject();
+        return Arrays.equals(list,(Date[])o);
+    }
+
+    public Object customArgTypedFixedList_date_3() throws Exception {
+        Date[] list = new Date[]{new Date(1560864000), new Date(1560864000), new Date(1560864000)};
+        Object o = input.readObject();
+        return Arrays.equals(list,(Date[])o);
+    }
+
+    public Object customArgTypedFixedList_arrays() throws Exception {
+        int[][][] list = new int[][][]{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}};
+        try {
+            Object o = input.readObject();
+            return Arrays.deepEquals(list, (int[][][])o);
+        } catch (Exception e){
+            return e.toString();
+        }
+    }
+
+    public Object customArgTypedFixedList_A0arrays() throws Exception {
+        A0[][][] list = new A0[][][]{{{new A0(), new A0(), new A0()}, {new A0(), new A0(), new A0(), null}}, {{new A0()}, {new A0()}}};
+        Object o = input.readObject();
+        return Arrays.deepEquals(list, (A0[][][])o);
+    }
+
+    public Object customArgTypedFixedList_Test() throws Exception {
+        TypedListTest t = new TypedListTest();
+        Object o = input.readObject();
+        TypedListTest t2 = (TypedListTest)o;
+        return t.a.equals(t.a) && Arrays.deepEquals(t.list, t2.list) && Arrays.deepEquals(t.list1, t2.list1);
+    }
+
+    public Object customArgTypedFixedList_Object() throws Exception {
+        Object[] list = new Object[]{new A0()};
+        Object o = input.readObject();
+        return Arrays.deepEquals(list, (Object[])o);
+    }
+
+    public Object customArgTypedFixedList_Decimal() throws Exception {
+        BigDecimal o = (BigDecimal) input.readObject();
+        return o.toString().equals( "100.256");
+    }
 }
\ No newline at end of file
diff --git a/test_hessian/src/main/java/test/TestCustomReply.java b/test_hessian/src/main/java/test/TestCustomReply.java
index e50a49a..21ada2a 100644
--- a/test_hessian/src/main/java/test/TestCustomReply.java
+++ b/test_hessian/src/main/java/test/TestCustomReply.java
@@ -19,9 +19,10 @@
 import com.caucho.hessian.test.A1;
 
 import java.io.OutputStream;
+import java.io.Serializable;
 import java.util.Date;
 import java.util.HashMap;
-
+import java.math.BigDecimal;
 
 public class TestCustomReply {
 
@@ -63,6 +64,7 @@
         typeMap.put(char[].class, "[char");
         typeMap.put(String[].class, "[string");
         typeMap.put(Object[].class, "[object");
+        typeMap.put(Date[].class, "[date");
     }
 
     public void customReplyTypedFixedListHasNull() throws Exception {
@@ -115,4 +117,245 @@
         }
         output.flush();
     }
-}
\ No newline at end of file
+
+    public void customReplyTypedFixedList_A0() throws Exception {
+        A0[] o = new A0[]{new A0(), new A0(), null};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_A0() throws Exception {
+        A0[] o = new A0[]{new A0(), new A0(), null};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, "[com.caucho.hessian.test.A0");
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_int() throws Exception {
+        int[] o = new int[]{1, 2, 3};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_int() throws Exception {
+        int[] o = new int[]{1, 2, 3};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_long() throws Exception {
+        long[] o = new long[]{1, 2, 3};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_long() throws Exception {
+        long[] o = new long[]{1, 2, 3};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_float() throws Exception {
+        float[] o = new float[]{1, 2, 3};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_float() throws Exception {
+        float[] o = new float[]{1, 2, 3};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_double() throws Exception {
+        double[] o = new double[]{1, 2, 3};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_double() throws Exception {
+        double[] o = new double[]{1, 2, 3};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_short() throws Exception {
+        short[] o = new short[]{1, 2, 3};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_short() throws Exception {
+        short[] o = new short[]{1, 2, 3};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_char() throws Exception {
+        char[] o = new char[]{'1', '2', '3'};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(o.length, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_char() throws Exception {
+        char[] o = new char[]{'1', '2', '3'};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_boolean() throws Exception {
+        boolean[] o = new boolean[]{true, false, true};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_boolean() throws Exception {
+        boolean[] o = new boolean[]{true, false, true};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_date() throws Exception {
+        Date[] o = new Date[]{new Date(1560864000), new Date(1560864000), new Date(1560864000)};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedVariableList_date() throws Exception {
+        Date[] o = new Date[]{new Date(1560864000), new Date(1560864000), new Date(1560864000)};
+        if (output.addRef(o)) {
+            return;
+        }
+        boolean hasEnd = output.writeListBegin(-1, typeMap.get(o.getClass()));
+        for (Object tmp: o) {
+            output.writeObject(tmp);
+        }
+        if (hasEnd) {
+            output.writeListEnd();
+        }
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_arrays() throws Exception {
+        int[][][] o = new int[][][]{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_A0arrays() throws Exception {
+        A0[][][] o = new A0[][][]{{{new A0(), new A0(), new A0()}, {new A0(), new A0(), new A0(), null}}, {{new A0()}, {new A0()}}};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_Test() throws Exception {
+        TypedListTest o = new TypedListTest();
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedFixedList_Object() throws Exception {
+        Object[] o = new Object[]{new A0()};
+        output.writeObject(o);
+        output.flush();
+    }
+
+    public void customReplyTypedFixedDecimal() throws Exception {
+        BigDecimal decimal = new BigDecimal("100.256");
+        output.writeObject(decimal);
+        output.flush();
+    }
+
+}
+
+class TypedListTest implements Serializable {
+    public A0 a;
+    public A0[][] list;
+    public A1[][] list1;
+    TypedListTest() {
+        this.a = new A0();
+        this.list = new A0[][]{{new A0(), new A0()},{new A0(), new A0()}};
+        this.list1 = new A1[][]{{new A1(), new A1()},{new A1(), new A1()}};
+    }
+
+}
diff --git a/test_hessian/src/main/java/test/TestThrowable.java b/test_hessian/src/main/java/test/TestThrowable.java
index e26f68a..faf4b64 100644
--- a/test_hessian/src/main/java/test/TestThrowable.java
+++ b/test_hessian/src/main/java/test/TestThrowable.java
@@ -15,11 +15,24 @@
 package test;
 
 import java.io.*;
+import java.lang.*;
+import java.lang.annotation.*;
+import java.lang.instrument.IllegalClassFormatException;
 import java.lang.invoke.WrongMethodTypeException;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.instrument.UnmodifiableClassException;
 import java.lang.reflect.*;
+import java.time.DateTimeException;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.time.zone.ZoneRulesException;
 import java.util.*;
-import java.util.concurrent.CompletionException;
-import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.*;
+import java.util.jar.JarException;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.InvalidPreferencesFormatException;
+import java.util.zip.DataFormatException;
+import java.util.zip.ZipException;
 
 public class TestThrowable {
   public static Object throw_exception() {
@@ -52,7 +65,7 @@
 
   public static Object throw_uncheckedIOException() {
     return new java.io.UncheckedIOException(
-        "uncheckedIOException", new java.io.IOException("io exception"));
+            "uncheckedIOException", new java.io.IOException("io exception"));
   }
 
   public static Object throw_runtimeException() {
@@ -124,7 +137,7 @@
   }
 
   public static Object throw_OptionalDataException()
-      throws InvocationTargetException, NoSuchMethodException, IllegalAccessException,
+          throws InvocationTargetException, NoSuchMethodException, IllegalAccessException,
           InstantiationException {
     Constructor c1 = OptionalDataException.class.getDeclaredConstructor(int.class);
     c1.setAccessible(true);
@@ -143,6 +156,26 @@
     return new UTFDataFormatException("UTFDataFormatException");
   }
 
+  public static Object throw_CloneNotSupportedException() {
+    return new CloneNotSupportedException("CloneNotSupportedException");
+  }
+
+  public static Object throw_InterruptedException() {
+    return new InterruptedException("InterruptedException");
+  }
+
+  public static Object throw_InterruptedIOException() {
+    return new InterruptedIOException("InterruptedIOException");
+  }
+
+  public static Object throw_LambdaConversionException() {
+    return new LambdaConversionException("LambdaConversionException");
+  }
+
+  public static Object throw_UnmodifiableClassException() {
+    return new UnmodifiableClassException("UnmodifiableClassException");
+  }
+
   public static Object throw_SecurityException() {
     return new SecurityException("SecurityException");
   }
@@ -189,7 +222,7 @@
 
   public static Object throw_MissingResourceException() {
     return new MissingResourceException(
-        "MissingResourceException", "MissingResourceExceptionClass", "MissingResourceExceptionKey");
+            "MissingResourceException", "MissingResourceExceptionClass", "MissingResourceExceptionKey");
   }
 
   public static Object throw_ConcurrentModificationException() {
@@ -217,4 +250,144 @@
   public static Object throw_NoSuchElementException() {
     return new NoSuchElementException("NoSuchElementException");
   }
+
+  public static Object throw_NegativeArraySizeException() {
+    return new NegativeArraySizeException("NegativeArraySizeException");
+  }
+
+  public static Object throw_UnsupportedOperationException() {
+    return new UnsupportedOperationException("UnsupportedOperationException");
+  }
+
+  public static Object throw_ArithmeticException() {
+    return new ArithmeticException("ArithmeticException");
+  }
+
+  public static Object throw_InputMismatchException() {
+    return new InputMismatchException("InputMismatchException");
+  }
+
+  public static Object throw_ExecutionException() {
+    return new ExecutionException("ExecutionException", new Throwable("exception"));
+  }
+
+  public static Object throw_InvalidPreferencesFormatException() {
+    return new InvalidPreferencesFormatException("InvalidPreferencesFormatException", new Throwable("exception"));
+  }
+
+  public static Object throw_TimeoutException() {
+    return new TimeoutException("TimeoutException");
+  }
+
+  public static Object throw_BackingStoreException() {
+    return new BackingStoreException("BackingStoreException");
+  }
+
+  public static Object throw_DataFormatException() {
+    return new DataFormatException("DataFormatException");
+  }
+
+  public static Object throw_BrokenBarrierException() {
+    return new BrokenBarrierException("BrokenBarrierException");
+  }
+
+  public static Object throw_TooManyListenersException() {
+    return new TooManyListenersException("TooManyListenersException");
+  }
+
+  public static Object throw_InvalidPropertiesFormatException() {
+    return new InvalidPropertiesFormatException("InvalidPropertiesFormatException");
+  }
+
+  public static Object throw_ZipException() {
+    return new ZipException("ZipException");
+  }
+
+  public static Object throw_JarException() {
+    return new JarException("JarException");
+  }
+
+  public static Object throw_IllegalClassFormatException() {
+    return new IllegalClassFormatException("IllegalClassFormatException");
+  }
+
+  public static Object throw_ReflectiveOperationException() {
+    return new ReflectiveOperationException("ReflectiveOperationException", new Throwable("exception"));
+  }
+
+  public static Object throw_InvocationTargetException() {
+    return new InvocationTargetException(new Throwable("exception"), "InvocationTargetException");
+  }
+
+  public static Object throw_NoSuchMethodException() {
+    return new NoSuchMethodException("NoSuchMethodException");
+  }
+
+  public static Object throw_NoSuchFieldException() {
+    return new NoSuchFieldException("NoSuchFieldException");
+  }
+
+  public static Object throw_IllegalAccessException() {
+    return new IllegalAccessException("IllegalAccessException");
+  }
+
+  public static Object throw_ClassNotFoundException() {
+    return new ClassNotFoundException("ClassNotFoundException", new Throwable("exception"));
+  }
+
+  public static Object throw_InstantiationException() {
+    return new InstantiationException("InstantiationException");
+  }
+
+  public static Object throw_DateTimeException() {
+    return new DateTimeException("DateTimeException", new Throwable("exception"));
+  }
+
+  public static Object throw_UnsupportedTemporalTypeException() {
+    return new UnsupportedTemporalTypeException("UnsupportedTemporalTypeException", new Throwable("exception"));
+  }
+
+  public static Object throw_ZoneRulesException() {
+    return new ZoneRulesException("ZoneRulesException", new Throwable("exception"));
+  }
+
+  public static Object throw_DateTimeParseException() {
+    return new DateTimeParseException("DateTimeParseException", "CharSequence", 1, new Throwable("exception"));
+  }
+
+  public static Object throw_FormatterClosedException() {
+    return new FormatterClosedException();
+  }
+
+  public static Object throw_CancellationException() {
+    return new CancellationException("CancellationException");
+  }
+
+  public static Object throw_UnknownFormatConversionException() {
+    return new UnknownFormatConversionException("UnknownFormatConversionException");
+  }
+
+  public static Object throw_UnknownFormatFlagsException() {
+    return new UnknownFormatFlagsException("UnknownFormatFlagsException");
+  }
+
+  public static Object throw_IllegalFormatFlagsException() {
+    return new IllegalFormatFlagsException("IllegalFormatFlagsException");
+  }
+
+  public static Object throw_IllegalFormatPrecisionException() {
+    return new IllegalFormatPrecisionException(1);
+  }
+
+  public static Object throw_IllegalFormatCodePointException() {
+    return new IllegalFormatCodePointException(1);
+  }
+
+  public static Object throw_MissingFormatArgumentException() {
+    return new MissingFormatArgumentException("MissingFormatArgumentException");
+  }
+
+  public static Object throw_MissingFormatWidthException() {
+    return new MissingFormatWidthException("MissingFormatWidthException");
+  }
 }