diff options
107 files changed, 5142 insertions, 3450 deletions
diff --git a/README.version b/README.version index 614fcde..95ae353 100644 --- a/README.version +++ b/README.version @@ -1,6 +1,6 @@ URL: https://github.com/easymock/objenesis -Version: 2.0 +Version: 2.5 BugComponent: 21001 Local Modifications: - None + None diff --git a/main/.settings/org.eclipse.jdt.core.prefs b/main/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 302c5cb..0000000 --- a/main/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,296 +0,0 @@ -eclipse.preferences.version=1
-org.eclipse.jdt.core.codeComplete.argumentPrefixes=
-org.eclipse.jdt.core.codeComplete.argumentSuffixes=
-org.eclipse.jdt.core.codeComplete.fieldPrefixes=
-org.eclipse.jdt.core.codeComplete.fieldSuffixes=
-org.eclipse.jdt.core.codeComplete.localPrefixes=
-org.eclipse.jdt.core.codeComplete.localSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.3
-org.eclipse.jdt.core.compiler.compliance=1.3
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.3
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=0
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
-org.eclipse.jdt.core.formatter.comment.line_length=100
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=1
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=3
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=true
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=100
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=3
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/main/.settings/org.eclipse.jdt.ui.prefs b/main/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index cdfe61e..0000000 --- a/main/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,10 +0,0 @@ -eclipse.preferences.version=1
-formatter_profile=_Objenesis
-formatter_settings_version=12
-internal.default.compliance=user
-org.eclipse.jdt.ui.exception.name=e
-org.eclipse.jdt.ui.gettersetter.use.is=true
-org.eclipse.jdt.ui.javadoc=false
-org.eclipse.jdt.ui.keywordthis=false
-org.eclipse.jdt.ui.overrideannotation=true
-org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
diff --git a/main/assembly.xml b/main/assembly.xml index 0c28778..8e9c3b3 100644 --- a/main/assembly.xml +++ b/main/assembly.xml @@ -1,40 +1,40 @@ -<!--
-
- Copyright 2006-2013 the original author or authors.
-
- 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.
-
--->
-<assembly>
- <id>bin</id>
- <formats>
- <format>zip</format>
- </formats>
- <fileSets>
- <fileSet>
- <directory>${project.build.outputDirectory}/META-INF</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>NOTICE</include>
- <include>LICENSE</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>${project.build.directory}</directory>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
+<!-- + + Copyright 2006-2017 the original author or authors. + + 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. + +--> +<assembly> + <id>bin</id> + <formats> + <format>zip</format> + </formats> + <fileSets> + <fileSet> + <directory>${project.build.outputDirectory}/META-INF</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>NOTICE</include> + <include>LICENSE</include> + </includes> + </fileSet> + <fileSet> + <directory>${project.build.directory}</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>*.jar</include> + </includes> + </fileSet> + </fileSets> </assembly>
\ No newline at end of file diff --git a/main/pom.xml b/main/pom.xml index 10f993b..3af2ef4 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -1,78 +1,90 @@ -<?xml version="1.0" encoding="ISO-8859-1"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.objenesis</groupId>
- <artifactId>objenesis-parent</artifactId>
- <version>2.0-SNAPSHOT</version>
- </parent>
- <artifactId>objenesis</artifactId>
-
- <name>Objenesis</name>
- <description>A library for instantiating Java objects</description>
- <url>http://objenesis.org</url>
-
- <dependencies />
-
- <build>
- <plugins>
- <plugin>
- <groupId>com.keyboardsamurais.maven</groupId>
- <artifactId>maven-timestamp-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>com.google.code.maven-license-plugin</groupId>
- <artifactId>maven-license-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-remote-resources-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>
- COM.jrockit.reflect;resolution:=optional,
- jrockit.vm;resolution:=optional,
- COM.newmonics.PercClassloader;resolution:=optional,
- sun.reflect;resolution:=optional
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <!-- Activate to create the release bundle -->
- <id>release</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <attach>false</attach>
- <descriptors>
- <descriptor>assembly.xml</descriptor>
- </descriptors>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
+<?xml version="1.0" encoding="ISO-8859-1"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.objenesis</groupId> + <artifactId>objenesis-parent</artifactId> + <version>2.5</version> + </parent> + <artifactId>objenesis</artifactId> + + <name>Objenesis</name> + <description>A library for instantiating Java objects</description> + <url>http://objenesis.org</url> + + <build> + <plugins> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> + </archive> + </configuration> + </plugin> + <plugin> + <groupId>com.keyboardsamurais.maven</groupId> + <artifactId>maven-timestamp-plugin</artifactId> + </plugin> + <plugin> + <groupId>com.mycila.maven-license-plugin</groupId> + <artifactId>maven-license-plugin</artifactId> + </plugin> + <plugin> + <artifactId>maven-remote-resources-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Import-Package> + COM.newmonics.PercClassloader;resolution:=optional, + sun.misc;resolution:=optional, + sun.reflect;resolution:=optional + </Import-Package> + </instructions> + </configuration> + <executions> + <execution> + <id>bundle-manifest</id> + <phase>process-classes</phase> + <goals> + <goal>manifest</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <!-- Activate to create the release bundle --> + <id>release</id> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <attach>false</attach> + <descriptors> + <descriptor>assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/main/src/main/java/org/objenesis/Objenesis.java b/main/src/main/java/org/objenesis/Objenesis.java index 8bb29a5..893d426 100644 --- a/main/src/main/java/org/objenesis/Objenesis.java +++ b/main/src/main/java/org/objenesis/Objenesis.java @@ -1,44 +1,46 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Common interface to all kind of Objenesis objects
- *
- * @author Henri Tremblay
- */
-public interface Objenesis {
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- Object newInstance(Class clazz);
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- ObjectInstantiator getInstantiatorOf(Class clazz);
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.objenesis.instantiator.ObjectInstantiator; + +/** + * Common interface to all kind of Objenesis objects + * + * @author Henri Tremblay + */ +public interface Objenesis { + + /** + * Will create a new object without any constructor being called + * + * @param <T> Type instantiated + * @param clazz Class to instantiate + * @return New instance of clazz + */ + <T> T newInstance(Class<T> clazz); + + /** + * Will pick the best instantiator for the provided class. If you need to create a lot of + * instances from the same class, it is way more efficient to create them from the same + * ObjectInstantiator than calling {@link #newInstance(Class)}. + * + * @param <T> Type to instantiate + * @param clazz Class to instantiate + * @return Instantiator dedicated to the class + */ + <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz); +} diff --git a/main/src/main/java/org/objenesis/ObjenesisBase.java b/main/src/main/java/org/objenesis/ObjenesisBase.java index 24bb444..7427200 100644 --- a/main/src/main/java/org/objenesis/ObjenesisBase.java +++ b/main/src/main/java/org/objenesis/ObjenesisBase.java @@ -1,96 +1,102 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.objenesis.instantiator.ObjectInstantiator;
-import org.objenesis.strategy.InstantiatorStrategy;
-
-/**
- * Base class to extend if you want to have a class providing your own default strategy. Can also be
- * instantiated directly.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisBase implements Objenesis {
-
- /** Strategy used by this Objenesi implementation to create classes */
- protected final InstantiatorStrategy strategy;
-
- /** Strategy cache. Key = Class, Value = InstantiatorStrategy */
- protected Map cache;
-
- /**
- * Constructor allowing to pick a strategy and using cache
- *
- * @param strategy Strategy to use
- */
- public ObjenesisBase(InstantiatorStrategy strategy) {
- this(strategy, true);
- }
-
- /**
- * Flexible constructor allowing to pick the strategy and if caching should be used
- *
- * @param strategy Strategy to use
- * @param useCache If {@link ObjectInstantiator}s should be cached
- */
- public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) {
- if(strategy == null) {
- throw new IllegalArgumentException("A strategy can't be null");
- }
- this.strategy = strategy;
- this.cache = useCache ? new HashMap() : null;
- }
-
- public String toString() {
- return getClass().getName() + " using " + strategy.getClass().getName()
- + (cache == null ? " without" : " with") + " caching";
- }
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public Object newInstance(Class clazz) {
- return getInstantiatorOf(clazz).newInstance();
- }
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- public synchronized ObjectInstantiator getInstantiatorOf(Class clazz) {
- if(cache == null) {
- return strategy.newInstantiatorOf(clazz);
- }
- ObjectInstantiator instantiator = (ObjectInstantiator) cache.get(clazz.getName());
- if(instantiator == null) {
- instantiator = strategy.newInstantiatorOf(clazz);
- cache.put(clazz.getName(), instantiator);
- }
- return instantiator;
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.strategy.InstantiatorStrategy; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Base class to extend if you want to have a class providing your own default strategy. Can also be + * instantiated directly. + * + * @author Henri Tremblay + */ +public class ObjenesisBase implements Objenesis { + + /** Strategy used by this Objenesi implementation to create classes */ + protected final InstantiatorStrategy strategy; + + /** Strategy cache. Key = Class, Value = InstantiatorStrategy */ + protected ConcurrentHashMap<String, ObjectInstantiator<?>> cache; + + /** + * Constructor allowing to pick a strategy and using cache + * + * @param strategy Strategy to use + */ + public ObjenesisBase(InstantiatorStrategy strategy) { + this(strategy, true); + } + + /** + * Flexible constructor allowing to pick the strategy and if caching should be used + * + * @param strategy Strategy to use + * @param useCache If {@link ObjectInstantiator}s should be cached + */ + public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) { + if(strategy == null) { + throw new IllegalArgumentException("A strategy can't be null"); + } + this.strategy = strategy; + this.cache = useCache ? new ConcurrentHashMap<String, ObjectInstantiator<?>>() : null; + } + + @Override + public String toString() { + return getClass().getName() + " using " + strategy.getClass().getName() + + (cache == null ? " without" : " with") + " caching"; + } + + /** + * Will create a new object without any constructor being called + * + * @param clazz Class to instantiate + * @return New instance of clazz + */ + public <T> T newInstance(Class<T> clazz) { + return getInstantiatorOf(clazz).newInstance(); + } + + /** + * Will pick the best instantiator for the provided class. If you need to create a lot of + * instances from the same class, it is way more efficient to create them from the same + * ObjectInstantiator than calling {@link #newInstance(Class)}. + * + * @param clazz Class to instantiate + * @return Instantiator dedicated to the class + */ + @SuppressWarnings("unchecked") + public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { + if(clazz.isPrimitive()) { + throw new IllegalArgumentException("Primitive types can't be instantiated in Java"); + } + if(cache == null) { + return strategy.newInstantiatorOf(clazz); + } + ObjectInstantiator<?> instantiator = cache.get(clazz.getName()); + if(instantiator == null) { + ObjectInstantiator<?> newInstantiator = strategy.newInstantiatorOf(clazz); + instantiator = cache.putIfAbsent(clazz.getName(), newInstantiator); + if(instantiator == null) { + instantiator = newInstantiator; + } + } + return (ObjectInstantiator<T>) instantiator; + } +} diff --git a/main/src/main/java/org/objenesis/ObjenesisException.java b/main/src/main/java/org/objenesis/ObjenesisException.java index f192dbe..3ae54dd 100644 --- a/main/src/main/java/org/objenesis/ObjenesisException.java +++ b/main/src/main/java/org/objenesis/ObjenesisException.java @@ -1,59 +1,49 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-/**
- * Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is
- * runtime to prevent having to catch it. It will do normal exception wrapping for JDK 1.4 and more
- * and basic message wrapping for JDK 1.3.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisException extends RuntimeException {
-
- private static final long serialVersionUID = -2677230016262426968L;
-
- private static final boolean jdk14 = (Double.parseDouble(System
- .getProperty("java.specification.version")) > 1.3);
-
- /**
- * @param msg Error message
- */
- public ObjenesisException(String msg) {
- super(msg);
- }
-
- /**
- * @param cause Wrapped exception. The message will be the one of the cause.
- */
- public ObjenesisException(Throwable cause) {
- super(cause == null ? null : cause.toString());
- if(jdk14) {
- initCause(cause);
- }
- }
-
- /**
- * @param msg Error message
- * @param cause Wrapped exception
- */
- public ObjenesisException(String msg, Throwable cause) {
- super(msg);
- if(jdk14) {
- initCause(cause);
- }
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +/** + * Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is + * runtime to prevent having to catch it. + * + * @author Henri Tremblay + */ +public class ObjenesisException extends RuntimeException { + + private static final long serialVersionUID = -2677230016262426968L; + + /** + * @param msg Error message + */ + public ObjenesisException(String msg) { + super(msg); + } + + /** + * @param cause Wrapped exception. The message will be the one of the cause. + */ + public ObjenesisException(Throwable cause) { + super(cause); + } + + /** + * @param msg Error message + * @param cause Wrapped exception + */ + public ObjenesisException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/main/src/main/java/org/objenesis/ObjenesisHelper.java b/main/src/main/java/org/objenesis/ObjenesisHelper.java index 2e86305..8a947f3 100644 --- a/main/src/main/java/org/objenesis/ObjenesisHelper.java +++ b/main/src/main/java/org/objenesis/ObjenesisHelper.java @@ -1,80 +1,84 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import java.io.Serializable;
-
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Use Objenesis in a static way. <strong>It is strongly not recommended to use this class.</strong>
- *
- * @author Henri Tremblay
- */
-public final class ObjenesisHelper {
-
- private static final Objenesis OBJENESIS_STD = new ObjenesisStd();
-
- private static final Objenesis OBJENESIS_SERIALIZER = new ObjenesisSerializer();
-
- private ObjenesisHelper() {
- }
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public static Object newInstance(Class clazz) {
- return OBJENESIS_STD.newInstance(clazz);
- }
-
- /**
- * Will create an object just like it's done by ObjectInputStream.readObject (the default
- * constructor of the first non serializable class will be called)
- *
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public static Serializable newSerializableInstance(Class clazz) {
- return (Serializable) OBJENESIS_SERIALIZER.newInstance(clazz);
- }
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- public static ObjectInstantiator getInstantiatorOf(Class clazz) {
- return OBJENESIS_STD.getInstantiatorOf(clazz);
- }
-
- /**
- * Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating
- * ObjectInputStream.readObject behavior.
- *
- * @see #newSerializableInstance(Class)
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- public static ObjectInstantiator getSerializableObjectInstantiatorOf(Class clazz) {
- return OBJENESIS_SERIALIZER.getInstantiatorOf(clazz);
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import java.io.Serializable; + +import org.objenesis.instantiator.ObjectInstantiator; + +/** + * Use Objenesis in a static way. <strong>It is strongly not recommended to use this class.</strong> + * + * @author Henri Tremblay + */ +public final class ObjenesisHelper { + + private static final Objenesis OBJENESIS_STD = new ObjenesisStd(); + + private static final Objenesis OBJENESIS_SERIALIZER = new ObjenesisSerializer(); + + private ObjenesisHelper() { + } + + /** + * Will create a new object without any constructor being called + * + * @param <T> Type instantiated + * @param clazz Class to instantiate + * @return New instance of clazz + */ + public static <T> T newInstance(Class<T> clazz) { + return OBJENESIS_STD.newInstance(clazz); + } + + /** + * Will create an object just like it's done by ObjectInputStream.readObject (the default + * constructor of the first non serializable class will be called) + * + * @param <T> Type instantiated + * @param clazz Class to instantiate + * @return New instance of clazz + */ + public static <T extends Serializable> T newSerializableInstance(Class<T> clazz) { + return (T) OBJENESIS_SERIALIZER.newInstance(clazz); + } + + /** + * Will pick the best instantiator for the provided class. If you need to create a lot of + * instances from the same class, it is way more efficient to create them from the same + * ObjectInstantiator than calling {@link #newInstance(Class)}. + * + * @param <T> Type to instantiate + * @param clazz Class to instantiate + * @return Instantiator dedicated to the class + */ + public static <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { + return OBJENESIS_STD.getInstantiatorOf(clazz); + } + + /** + * Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating + * ObjectInputStream.readObject behavior. + * + * @see #newSerializableInstance(Class) + * @param <T> Type to instantiate + * @param clazz Class to instantiate + * @return Instantiator dedicated to the class + */ + public static <T extends Serializable> ObjectInstantiator<T> getSerializableObjectInstantiatorOf(Class<T> clazz) { + return OBJENESIS_SERIALIZER.getInstantiatorOf(clazz); + } +} diff --git a/main/src/main/java/org/objenesis/ObjenesisSerializer.java b/main/src/main/java/org/objenesis/ObjenesisSerializer.java index 8bb7e8c..be92b9d 100644 --- a/main/src/main/java/org/objenesis/ObjenesisSerializer.java +++ b/main/src/main/java/org/objenesis/ObjenesisSerializer.java @@ -1,43 +1,43 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import org.objenesis.strategy.SerializingInstantiatorStrategy;
-
-/**
- * Objenesis implementation using the {@link SerializingInstantiatorStrategy}.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisSerializer extends ObjenesisBase {
-
- /**
- * Default constructor using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy}
- */
- public ObjenesisSerializer() {
- super(new SerializingInstantiatorStrategy());
- }
-
- /**
- * Instance using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching
- * {@link org.objenesis.instantiator.ObjectInstantiator}s
- *
- * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached
- */
- public ObjenesisSerializer(boolean useCache) {
- super(new SerializingInstantiatorStrategy(), useCache);
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.objenesis.strategy.SerializingInstantiatorStrategy; + +/** + * Objenesis implementation using the {@link SerializingInstantiatorStrategy}. + * + * @author Henri Tremblay + */ +public class ObjenesisSerializer extends ObjenesisBase { + + /** + * Default constructor using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy} + */ + public ObjenesisSerializer() { + super(new SerializingInstantiatorStrategy()); + } + + /** + * Instance using the {@link org.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching + * {@link org.objenesis.instantiator.ObjectInstantiator}s + * + * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached + */ + public ObjenesisSerializer(boolean useCache) { + super(new SerializingInstantiatorStrategy(), useCache); + } +} diff --git a/main/src/main/java/org/objenesis/ObjenesisStd.java b/main/src/main/java/org/objenesis/ObjenesisStd.java index 2d9b9ba..16d21c6 100644 --- a/main/src/main/java/org/objenesis/ObjenesisStd.java +++ b/main/src/main/java/org/objenesis/ObjenesisStd.java @@ -1,43 +1,43 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import org.objenesis.strategy.StdInstantiatorStrategy;
-
-/**
- * Objenesis implementation using the {@link org.objenesis.strategy.StdInstantiatorStrategy}.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisStd extends ObjenesisBase {
-
- /**
- * Default constructor using the {@link org.objenesis.strategy.StdInstantiatorStrategy}
- */
- public ObjenesisStd() {
- super(new StdInstantiatorStrategy());
- }
-
- /**
- * Instance using the {@link org.objenesis.strategy.StdInstantiatorStrategy} with or without
- * caching {@link org.objenesis.instantiator.ObjectInstantiator}s
- *
- * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached
- */
- public ObjenesisStd(boolean useCache) {
- super(new StdInstantiatorStrategy(), useCache);
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.objenesis.strategy.StdInstantiatorStrategy; + +/** + * Objenesis implementation using the {@link org.objenesis.strategy.StdInstantiatorStrategy}. + * + * @author Henri Tremblay + */ +public class ObjenesisStd extends ObjenesisBase { + + /** + * Default constructor using the {@link org.objenesis.strategy.StdInstantiatorStrategy} + */ + public ObjenesisStd() { + super(new StdInstantiatorStrategy()); + } + + /** + * Instance using the {@link org.objenesis.strategy.StdInstantiatorStrategy} with or without + * caching {@link org.objenesis.instantiator.ObjectInstantiator}s + * + * @param useCache If {@link org.objenesis.instantiator.ObjectInstantiator}s should be cached + */ + public ObjenesisStd(boolean useCache) { + super(new StdInstantiatorStrategy(), useCache); + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java b/main/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java index 47b1713..d6db8ba 100644 --- a/main/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/ObjectInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ package org.objenesis.instantiator; * * @author Leonardo Mesquita */ -public interface ObjectInstantiator { +public interface ObjectInstantiator<T> { /** * Returns a new instance of an object. The returned object's class is defined by the @@ -28,6 +28,6 @@ public interface ObjectInstantiator { * * @return A new instance of an object. */ - Object newInstance(); + T newInstance(); } diff --git a/main/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java b/main/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java index f937979..deeb54b 100644 --- a/main/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java +++ b/main/src/main/java/org/objenesis/instantiator/SerializationInstantiatorHelper.java @@ -1,48 +1,49 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator;
-
-import java.io.Serializable;
-
-/**
- * Helper for common serialization-compatible instantiation functions
- *
- * @author Leonardo Mesquita
- */
-public class SerializationInstantiatorHelper {
-
- /**
- * Returns the first non-serializable superclass of a given class. According to Java Object
- * Serialization Specification, objects read from a stream are initialized by calling an
- * accessible no-arg constructor from the first non-serializable superclass in the object's
- * hierarchy, allowing the state of non-serializable fields to be correctly initialized.
- *
- * @param type Serializable class for which the first non-serializable superclass is to be found
- * @return The first non-serializable superclass of 'type'.
- * @see java.io.Serializable
- */
- public static Class getNonSerializableSuperClass(Class type) {
- Class result = type;
- while(Serializable.class.isAssignableFrom(result)) {
- result = result.getSuperclass();
- if(result == null) {
- throw new Error("Bad class hierarchy: No non-serializable parents");
- }
- }
- return result;
-
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator; + +import java.io.Serializable; + +/** + * Helper for common serialization-compatible instantiation functions + * + * @author Leonardo Mesquita + */ +public class SerializationInstantiatorHelper { + + /** + * Returns the first non-serializable superclass of a given class. According to Java Object + * Serialization Specification, objects read from a stream are initialized by calling an + * accessible no-arg constructor from the first non-serializable superclass in the object's + * hierarchy, allowing the state of non-serializable fields to be correctly initialized. + * + * @param <T> Type to instantiate + * @param type Serializable class for which the first non-serializable superclass is to be found + * @return The first non-serializable superclass of 'type'. + * @see java.io.Serializable + */ + public static <T> Class<? super T> getNonSerializableSuperClass(Class<T> type) { + Class<? super T> result = type; + while(Serializable.class.isAssignableFrom(result)) { + result = result.getSuperclass(); + if(result == null) { + throw new Error("Bad class hierarchy: No non-serializable parents"); + } + } + return result; + + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/android/Android10Instantiator.java b/main/src/main/java/org/objenesis/instantiator/android/Android10Instantiator.java new file mode 100644 index 0000000..496123d --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/android/Android10Instantiator.java @@ -0,0 +1,67 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.android; + +import java.io.ObjectInputStream; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiator for Android API level 10 and lover which creates objects without driving their + * constructors, using internal methods on the Dalvik implementation of + * {@link java.io.ObjectInputStream}. + * + * @author Piotr 'Qertoip' WÅ‚odarek + */ +@Instantiator(Typology.STANDARD) +public class Android10Instantiator<T> implements ObjectInstantiator<T> { + private final Class<T> type; + private final Method newStaticMethod; + + public Android10Instantiator(Class<T> type) { + this.type = type; + newStaticMethod = getNewStaticMethod(); + } + + public T newInstance() { + try { + return type.cast(newStaticMethod.invoke(null, type, Object.class)); + } + catch(Exception e) { + throw new ObjenesisException(e); + } + } + + private static Method getNewStaticMethod() { + try { + Method newStaticMethod = ObjectInputStream.class.getDeclaredMethod( + "newInstance", Class.class, Class.class); + newStaticMethod.setAccessible(true); + return newStaticMethod; + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + } + +} diff --git a/main/src/main/java/org/objenesis/instantiator/android/AndroidInstantiator.java b/main/src/main/java/org/objenesis/instantiator/android/Android17Instantiator.java index b3277e6..adc9b59 100644 --- a/main/src/main/java/org/objenesis/instantiator/android/AndroidInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/android/Android17Instantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,33 +15,36 @@ */ package org.objenesis.instantiator.android; -import org.objenesis.ObjenesisException; -import org.objenesis.instantiator.ObjectInstantiator; - import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + /** - * Instantiator for Android which creates objects without driving their constructors, using internal - * methods on the Dalvik implementation of {@link ObjectStreamClass}. - * + * Instantiator for Android API level 11 to 17 which creates objects without driving their + * constructors, using internal methods on the Dalvik implementation of {@link ObjectStreamClass}. + * * @author Ian Parkinson (Google Inc.) */ -public class AndroidInstantiator implements ObjectInstantiator { - private final Class type; +@Instantiator(Typology.STANDARD) +public class Android17Instantiator<T> implements ObjectInstantiator<T> { + private final Class<T> type; private final Method newInstanceMethod; private final Integer objectConstructorId; - public AndroidInstantiator(Class type) { + public Android17Instantiator(Class<T> type) { this.type = type; newInstanceMethod = getNewInstanceMethod(); objectConstructorId = findConstructorIdForJavaLangObjectConstructor(); } - public Object newInstance() { + public T newInstance() { try { - return newInstanceMethod.invoke(null, new Object[] {type, objectConstructorId}); + return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId)); } catch(Exception e) { throw new ObjenesisException(e); @@ -51,7 +54,7 @@ public class AndroidInstantiator implements ObjectInstantiator { private static Method getNewInstanceMethod() { try { Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( - "newInstance", new Class[] {Class.class, Integer.TYPE}); + "newInstance", Class.class, Integer.TYPE); newInstanceMethod.setAccessible(true); return newInstanceMethod; } @@ -66,10 +69,10 @@ public class AndroidInstantiator implements ObjectInstantiator { private static Integer findConstructorIdForJavaLangObjectConstructor() { try { Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( - "getConstructorId", new Class[] {Class.class}); + "getConstructorId", Class.class); newInstanceMethod.setAccessible(true); - return (Integer) newInstanceMethod.invoke(null, new Object[] {Object.class}); + return (Integer) newInstanceMethod.invoke(null, Object.class); } catch(RuntimeException e) { throw new ObjenesisException(e); diff --git a/main/src/main/java/org/objenesis/instantiator/android/Android18Instantiator.java b/main/src/main/java/org/objenesis/instantiator/android/Android18Instantiator.java new file mode 100644 index 0000000..d4e280c --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/android/Android18Instantiator.java @@ -0,0 +1,90 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.android; + +import java.io.ObjectStreamClass; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiator for Android API leve 18 and higher. Same as the version 17 but the + * <code>newInstance</code> now takes a long in parameter + * + * @author Henri Tremblay + */ +@Instantiator(Typology.STANDARD) +public class Android18Instantiator<T> implements ObjectInstantiator<T> { + private final Class<T> type; + private final Method newInstanceMethod; + private final Long objectConstructorId; + + public Android18Instantiator(Class<T> type) { + this.type = type; + newInstanceMethod = getNewInstanceMethod(); + objectConstructorId = findConstructorIdForJavaLangObjectConstructor(); + } + + public T newInstance() { + try { + return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId)); + } + catch(Exception e) { + throw new ObjenesisException(e); + } + } + + private static Method getNewInstanceMethod() { + try { + Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance", + Class.class, Long.TYPE); + newInstanceMethod.setAccessible(true); + return newInstanceMethod; + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + } + + private static Long findConstructorIdForJavaLangObjectConstructor() { + try { + Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("getConstructorId", + Class.class); + newInstanceMethod.setAccessible(true); + + return (Long) newInstanceMethod.invoke(null, Object.class); + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + catch(IllegalAccessException e) { + throw new ObjenesisException(e); + } + catch(InvocationTargetException e) { + throw new ObjenesisException(e); + } + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java b/main/src/main/java/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java index 1d9f029..6f2ab23 100644 --- a/main/src/main/java/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,34 +15,49 @@ */ package org.objenesis.instantiator.android; -import org.objenesis.ObjenesisException; -import org.objenesis.instantiator.ObjectInstantiator; - import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + /** * {@link ObjectInstantiator} for Android which creates objects using the constructor from the first * non-serializable parent class constructor, using internal methods on the Dalvik implementation of * {@link ObjectStreamClass}. - * + * * @author Ian Parkinson (Google Inc.) */ -public class AndroidSerializationInstantiator implements ObjectInstantiator { - private final Class type; +@Instantiator(Typology.SERIALIZATION) +public class AndroidSerializationInstantiator<T> implements ObjectInstantiator<T> { + private final Class<T> type; private final ObjectStreamClass objectStreamClass; private final Method newInstanceMethod; - public AndroidSerializationInstantiator(Class type) { + public AndroidSerializationInstantiator(Class<T> type) { this.type = type; newInstanceMethod = getNewInstanceMethod(); - objectStreamClass = ObjectStreamClass.lookupAny(type); + Method m = null; + try { + m = ObjectStreamClass.class.getMethod("lookupAny", Class.class); + } catch (NoSuchMethodException e) { + throw new ObjenesisException(e); + } + try { + objectStreamClass = (ObjectStreamClass) m.invoke(null, type); + } catch (IllegalAccessException e) { + throw new ObjenesisException(e); + } catch (InvocationTargetException e) { + throw new ObjenesisException(e); + } } - public Object newInstance() { + public T newInstance() { try { - return newInstanceMethod.invoke(objectStreamClass, new Object[] {type}); + return type.cast(newInstanceMethod.invoke(objectStreamClass, type)); } catch(IllegalAccessException e) { throw new ObjenesisException(e); @@ -58,7 +73,7 @@ public class AndroidSerializationInstantiator implements ObjectInstantiator { private static Method getNewInstanceMethod() { try { Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( - "newInstance", new Class[] {Class.class}); + "newInstance", Class.class); newInstanceMethod.setAccessible(true); return newInstanceMethod; } diff --git a/main/src/main/java/org/objenesis/instantiator/annotations/Instantiator.java b/main/src/main/java/org/objenesis/instantiator/annotations/Instantiator.java new file mode 100644 index 0000000..82186aa --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/annotations/Instantiator.java @@ -0,0 +1,38 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Denote that the class in an instantiator of a given type + * + * @author Henri Tremblay + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Instantiator { + + /** + * @return type of instantiator + */ + Typology value(); +} diff --git a/main/src/main/java/org/objenesis/instantiator/annotations/Typology.java b/main/src/main/java/org/objenesis/instantiator/annotations/Typology.java new file mode 100644 index 0000000..10682c1 --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/annotations/Typology.java @@ -0,0 +1,43 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.annotations; + +/** + * Possible types of instantiator + * @author Henri Tremblay + */ +public enum Typology { + /** + * Mark an instantiator used for standard instantiation (not calling a constructor). + */ + STANDARD, + + /** + * Mark an instantiator used for serialization. + */ + SERIALIZATION, + + /** + * Mark an instantiator that doesn't behave like a {@link #STANDARD} nor a {@link #SERIALIZATION} (e.g. calls a constructor, fails + * all the time, etc.) + */ + NOT_COMPLIANT, + + /** + * No type specified on the instantiator class + */ + UNKNOWN +} diff --git a/main/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java index e1b96a4..e7fcb99 100644 --- a/main/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/basic/AccessibleInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,21 @@ */ package org.objenesis.instantiator.basic; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + /** * Instantiates a class by grabbing the no-args constructor, making it accessible and then calling * Constructor.newInstance(). Although this still requires no-arg constructors, it can call * non-public constructors (if the security manager allows it). - * + * * @author Joe Walnes * @see org.objenesis.instantiator.ObjectInstantiator */ -public class AccessibleInstantiator extends ConstructorInstantiator { +@Instantiator(Typology.NOT_COMPLIANT) +public class AccessibleInstantiator<T> extends ConstructorInstantiator<T> { - public AccessibleInstantiator(Class type) { + public AccessibleInstantiator(Class<T> type) { super(type); if(constructor != null) { constructor.setAccessible(true); diff --git a/main/src/main/java/org/objenesis/instantiator/basic/ClassDefinitionUtils.java b/main/src/main/java/org/objenesis/instantiator/basic/ClassDefinitionUtils.java new file mode 100644 index 0000000..1f83a29 --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/basic/ClassDefinitionUtils.java @@ -0,0 +1,230 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +/* + * Copyright 2003,2004 The Apache Software Foundation + * + * 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. + */ + +import org.objenesis.ObjenesisException; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; + +/** + * Helper class for ProxyObjectInstantiator. We can see the details of a class specification + * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">here</a> + * + * @author Henri Tremblay + */ +public final class ClassDefinitionUtils { + + public static final byte OPS_aload_0 = 42; + public static final byte OPS_invokespecial = -73; // has two bytes parameters + public static final byte OPS_return = -79; + public static final byte OPS_new = -69; + public static final byte OPS_dup = 89; + public static final byte OPS_areturn = -80; + + public static final int CONSTANT_Utf8 = 1; + public static final int CONSTANT_Integer = 3; + public static final int CONSTANT_Float = 4; + public static final int CONSTANT_Long = 5; + public static final int CONSTANT_Double = 6; + public static final int CONSTANT_Class = 7; + public static final int CONSTANT_String = 8; + public static final int CONSTANT_Fieldref = 9; + public static final int CONSTANT_Methodref = 10; + public static final int CONSTANT_InterfaceMethodref = 11; + public static final int CONSTANT_NameAndType = 12; + public static final int CONSTANT_MethodHandle = 15; + public static final int CONSTANT_MethodType = 16; + public static final int CONSTANT_InvokeDynamic = 18; + + public static final int ACC_PUBLIC = 0x0001; // Declared public; may be accessed from outside its package. + public static final int ACC_FINAL = 0x0010; // Declared final; no subclasses allowed. + public static final int ACC_SUPER = 0x0020; // Treat superclass methods specially when invoked by the invokespecial instruction. + public static final int ACC_INTERFACE = 0x0200; // Is an interface, not a class. + public static final int ACC_ABSTRACT = 0x0400; // Declared abstract; must not be instantiated. + public static final int ACC_SYNTHETIC = 0x1000; // Declared synthetic; not present in the source code. + public static final int ACC_ANNOTATION = 0x2000; // Declared as an annotation type. + public static final int ACC_ENUM = 0x4000; // Declared as an enum type. + + public static final byte[] MAGIC = { (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe }; + public static final byte[] VERSION = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x31 }; // minor_version, major_version (Java 5) + + private ClassDefinitionUtils() { } + + private static Method DEFINE_CLASS; + private static final ProtectionDomain PROTECTION_DOMAIN; + + static { + PROTECTION_DOMAIN = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { + public ProtectionDomain run() { + return ClassDefinitionUtils.class.getProtectionDomain(); + } + }); + + AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + try { + Class<?> loader = Class.forName("java.lang.ClassLoader"); // JVM crash w/o this + DEFINE_CLASS = loader.getDeclaredMethod("defineClass", + new Class[]{ String.class, + byte[].class, + Integer.TYPE, + Integer.TYPE, + ProtectionDomain.class }); + DEFINE_CLASS.setAccessible(true); + } catch (ClassNotFoundException e) { + throw new ObjenesisException(e); + } catch (NoSuchMethodException e) { + throw new ObjenesisException(e); + } + return null; + } + }); + } + + /** + * Define a class in the provided class loader from the array of bytes. Inspired by cglib + * <code>ReflectUtils.defineClass</code> + * + * @param <T> type of the class returned + * @param className class name in the format <code>org.objenesis.MyClass</code> + * @param b bytes representing the class + * @param loader the class loader where the class will be loaded + * @return the newly loaded class + * @throws Exception whenever something goes wrong + */ + @SuppressWarnings("unchecked") + public static <T> Class<T> defineClass(String className, byte[] b, ClassLoader loader) + throws Exception { + Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), PROTECTION_DOMAIN }; + Class<T> c = (Class<T>) DEFINE_CLASS.invoke(loader, args); + // Force static initializers to run. + Class.forName(className, true, loader); + return c; + } + + /** + * Read the bytes of a class from the classpath + * + * @param className full class name including the package + * @return the bytes representing the class + * @throws IllegalArgumentException if the class is longer than 2500 bytes + * @throws IOException if we fail to read the class + */ + public static byte[] readClass(String className) throws IOException { + // convert to a resource + className = classNameToResource(className); + + byte[] b = new byte[2500]; // I'm assuming that I'm reading class that are not too big + + int length; + + InputStream in = ClassDefinitionUtils.class.getClassLoader().getResourceAsStream(className); + try { + length = in.read(b); + } + finally { + in.close(); + } + + if(length >= 2500) { + throw new IllegalArgumentException("The class is longer that 2500 bytes which is currently unsupported"); + } + + byte[] copy = new byte[length]; + System.arraycopy(b, 0, copy, 0, length); + return copy; + } + + /** + * Write all class bytes to a file. + * + * @param fileName file where the bytes will be written + * @param bytes bytes representing the class + * @throws IOException if we fail to write the class + */ + public static void writeClass(String fileName, byte[] bytes) throws IOException { + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName)); + try { + out.write(bytes); + } + finally { + out.close(); + } + } + + /** + * Will convert a class name to its name in the class definition format (e.g {@code org.objenesis.EmptyClass} + * becomes {@code org/objenesis/EmptyClass}) + * + * @param className full class name including the package + * @return the internal name + */ + public static String classNameToInternalClassName(String className) { + return className.replace('.', '/'); + } + + /** + * Will convert a class name to its class loader resource name (e.g {@code org.objenesis.EmptyClass} + * becomes {@code org/objenesis/EmptyClass.class}) + * + * @param className full class name including the package + * @return the resource name + */ + public static String classNameToResource(String className) { + return classNameToInternalClassName(className) + ".class"; + } + + /** + * Check if this class already exists in the class loader and return it if it does + * + * @param <T> type of the class returned + * @param classLoader Class loader where to search the class + * @param className Class name with full path + * @return the class if it already exists or null + */ + @SuppressWarnings("unchecked") + public static <T> Class<T> getExistingClass(ClassLoader classLoader, String className) { + try { + return (Class<T>) Class.forName(className, true, classLoader); + } + catch (ClassNotFoundException e) { + return null; + } + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java index 7db10f5..b2b6ad2 100644 --- a/main/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/basic/ConstructorInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,19 +19,23 @@ import java.lang.reflect.Constructor; import org.objenesis.ObjenesisException; import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; /** * Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance(). * This can deal with default public constructors, but that's about it. - * + * * @author Joe Walnes + * @param <T> Type instantiated * @see ObjectInstantiator */ -public class ConstructorInstantiator implements ObjectInstantiator { +@Instantiator(Typology.NOT_COMPLIANT) +public class ConstructorInstantiator<T> implements ObjectInstantiator<T> { - protected Constructor constructor; + protected Constructor<T> constructor; - public ConstructorInstantiator(Class type) { + public ConstructorInstantiator(Class<T> type) { try { constructor = type.getDeclaredConstructor((Class[]) null); } @@ -40,7 +44,7 @@ public class ConstructorInstantiator implements ObjectInstantiator { } } - public Object newInstance() { + public T newInstance() { try { return constructor.newInstance((Object[]) null); } diff --git a/main/src/main/java/org/objenesis/instantiator/basic/FailingInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/FailingInstantiator.java new file mode 100644 index 0000000..b620642 --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/basic/FailingInstantiator.java @@ -0,0 +1,40 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * The instantiator that always throws an exception. Mainly used for tests + * + * @author Henri Tremblay + */ +@Instantiator(Typology.NOT_COMPLIANT) +public class FailingInstantiator<T> implements ObjectInstantiator<T> { + + public FailingInstantiator(Class<T> type) { + } + + /** + * @return Always throwing an exception + */ + public T newInstance() { + throw new ObjenesisException("Always failing"); + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java index e95f0f8..4080839 100644 --- a/main/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/basic/NewInstanceInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,26 +17,29 @@ package org.objenesis.instantiator.basic; import org.objenesis.ObjenesisException; import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; /** * The simplest instantiator - simply calls Class.newInstance(). This can deal with default public * constructors, but that's about it. - * + * * @author Joe Walnes * @see ObjectInstantiator */ -public class NewInstanceInstantiator implements ObjectInstantiator { +@Instantiator(Typology.NOT_COMPLIANT) +public class NewInstanceInstantiator<T> implements ObjectInstantiator<T> { - private final Class type; + private final Class<T> type; - public NewInstanceInstantiator(Class type) { + public NewInstanceInstantiator(Class<T> type) { this.type = type; } - public Object newInstance() { + public T newInstance() { try { return type.newInstance(); - } + } catch(Exception e) { throw new ObjenesisException(e); } diff --git a/main/src/main/java/org/objenesis/instantiator/basic/NullInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/NullInstantiator.java new file mode 100644 index 0000000..1429118 --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/basic/NullInstantiator.java @@ -0,0 +1,39 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * The instantiator that always return a null instance + * + * @author Henri Tremblay + */ +@Instantiator(Typology.NOT_COMPLIANT) +public class NullInstantiator<T> implements ObjectInstantiator<T> { + + public NullInstantiator(Class<T> type) { + } + + /** + * @return Always null + */ + public T newInstance() { + return null; + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java index 265f813..cf598d4 100644 --- a/main/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ import java.io.Serializable; import org.objenesis.ObjenesisException; import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; /** * Instantiates a class by using a dummy input stream that always feeds data for an empty object of @@ -34,11 +36,12 @@ import org.objenesis.instantiator.ObjectInstantiator; * defines a "readResolve" method, since it may return objects that have been returned previously * (i.e., there's no guarantee that the returned object is a new one), or even objects from a * completely different class. - * + * * @author Leonardo Mesquita * @see org.objenesis.instantiator.ObjectInstantiator */ -public class ObjectInputStreamInstantiator implements ObjectInstantiator { +@Instantiator(Typology.SERIALIZATION) +public class ObjectInputStreamInstantiator<T> implements ObjectInstantiator<T> { private static class MockStream extends InputStream { private int pointer; @@ -77,7 +80,7 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { } - public MockStream(Class clazz) { + public MockStream(Class<?> clazz) { this.pointer = 0; this.sequence = 0; this.data = HEADER; @@ -116,6 +119,7 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { data = buffers[sequence]; } + @Override public int read() throws IOException { int result = data[pointer++]; if(pointer >= data.length) { @@ -125,10 +129,12 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { return result; } + @Override public int available() throws IOException { return Integer.MAX_VALUE; } + @Override public int read(byte[] b, int off, int len) throws IOException { int left = len; int remaining = data.length - pointer; @@ -151,7 +157,7 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { private ObjectInputStream inputStream; - public ObjectInputStreamInstantiator(Class clazz) { + public ObjectInputStreamInstantiator(Class<T> clazz) { if(Serializable.class.isAssignableFrom(clazz)) { try { this.inputStream = new ObjectInputStream(new MockStream(clazz)); @@ -161,14 +167,15 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { } } else { - throw new ObjenesisException(new NotSerializableException(clazz+" not serializable")); + throw new ObjenesisException(new NotSerializableException(clazz + " not serializable")); } } - public Object newInstance() { + @SuppressWarnings("unchecked") + public T newInstance() { try { - return inputStream.readObject(); - } + return (T) inputStream.readObject(); + } catch(ClassNotFoundException e) { throw new Error("ClassNotFoundException: " + e.getMessage()); } diff --git a/main/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java index 742ec5a..7aac1df 100644 --- a/main/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java @@ -1,72 +1,75 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.basic;
-
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Instantiates a class by using reflection to make a call to private method
- * ObjectStreamClass.newInstance, present in many JVM implementations. This instantiator will create
- * classes in a way compatible with serialization, calling the first non-serializable superclass'
- * no-arg constructor.
- *
- * @author Leonardo Mesquita
- * @see ObjectInstantiator
- * @see java.io.Serializable
- */
-public class ObjectStreamClassInstantiator implements ObjectInstantiator {
-
- private static Method newInstanceMethod;
-
- private static void initialize() {
- if(newInstanceMethod == null) {
- try {
- newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance",
- new Class[] {});
- newInstanceMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- private final ObjectStreamClass objStreamClass;
-
- public ObjectStreamClassInstantiator(Class type) {
- initialize();
- objStreamClass = ObjectStreamClass.lookup(type);
- }
-
- public Object newInstance() {
-
- try {
- return newInstanceMethod.invoke(objStreamClass, new Object[] {});
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
-
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import java.io.ObjectStreamClass; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiates a class by using reflection to make a call to private method + * ObjectStreamClass.newInstance, present in many JVM implementations. This instantiator will create + * classes in a way compatible with serialization, calling the first non-serializable superclass' + * no-arg constructor. + * + * @author Leonardo Mesquita + * @see ObjectInstantiator + * @see java.io.Serializable + */ +@Instantiator(Typology.SERIALIZATION) +public class ObjectStreamClassInstantiator<T> implements ObjectInstantiator<T> { + + private static Method newInstanceMethod; + + private static void initialize() { + if(newInstanceMethod == null) { + try { + newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance"); + newInstanceMethod.setAccessible(true); + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + } + } + + private final ObjectStreamClass objStreamClass; + + public ObjectStreamClassInstantiator(Class<T> type) { + initialize(); + objStreamClass = ObjectStreamClass.lookup(type); + } + + @SuppressWarnings("unchecked") + public T newInstance() { + + try { + return (T) newInstanceMethod.invoke(objStreamClass); + } + catch(Exception e) { + throw new ObjenesisException(e); + } + + } + +} diff --git a/main/src/main/java/org/objenesis/instantiator/basic/ProxyingInstantiator.java b/main/src/main/java/org/objenesis/instantiator/basic/ProxyingInstantiator.java new file mode 100644 index 0000000..e97558c --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/basic/ProxyingInstantiator.java @@ -0,0 +1,192 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import static org.objenesis.instantiator.basic.ClassDefinitionUtils.*; + +/** + * This instantiator creates a class by dynamically extending it. It will skip the call to the parent constructor + * in the bytecode. So that the constructor is indeed not called but you however instantiate a child class, not + * the actual class. The class loader will normally throw a {@code VerifyError} is you do that. However, using + * {@code -Xverify:none} shoud make it work + * + * @author Henri Tremblay + */ +@Instantiator(Typology.STANDARD) +public class ProxyingInstantiator<T> implements ObjectInstantiator<T> { + + private static final int INDEX_CLASS_THIS = 1; + private static final int INDEX_CLASS_SUPERCLASS = 2; + private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3; + private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4; + private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5; + private static final int INDEX_UTF8_CLASS = 7; + private static final int INDEX_UTF8_SUPERCLASS = 8; + + private static int CONSTANT_POOL_COUNT = 9; + + private static final byte[] CODE = { OPS_aload_0, OPS_return}; + private static final int CODE_ATTRIBUTE_LENGTH = 12 + CODE.length; + + private static final String SUFFIX = "$$$Objenesis"; + + private static final String CONSTRUCTOR_NAME = "<init>"; + private static final String CONSTRUCTOR_DESC = "()V"; + + private final Class<?> newType; + + public ProxyingInstantiator(Class<T> type) { + + byte[] classBytes = writeExtendingClass(type, SUFFIX); + + try { + newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type.getClassLoader()); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + @SuppressWarnings("unchecked") + public T newInstance() { + try { + return (T) newType.newInstance(); + } catch (InstantiationException e) { + throw new ObjenesisException(e); + } catch (IllegalAccessException e) { + throw new ObjenesisException(e); + } + } + + /** + * Will generate the bytes for a class extending the type passed in parameter. This class will + * only have an empty default constructor + * + * @param type type to extend + * @param suffix the suffix appended to the class name to create the next extending class name + * @return the byte for the class + * @throws ObjenesisException is something goes wrong + */ + private static byte[] writeExtendingClass(Class<?> type, String suffix) { + String parentClazz = classNameToInternalClassName(type.getName()); + String clazz = parentClazz + suffix; + + DataOutputStream in = null; + ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class + try { + in = new DataOutputStream(bIn); + + in.write(MAGIC); + in.write(VERSION); + in.writeShort(CONSTANT_POOL_COUNT); + + // set all the constant pool here + + // 1. class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_CLASS); + + // 2. super class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_SUPERCLASS); + + // 3. default constructor name + in.writeByte(CONSTANT_Utf8); + in.writeUTF(CONSTRUCTOR_NAME); + + // 4. default constructor description + in.writeByte(CONSTANT_Utf8); + in.writeUTF(CONSTRUCTOR_DESC); + + // 5. Code + in.writeByte(CONSTANT_Utf8); + in.writeUTF("Code"); + + // 6. Class name + in.writeByte(CONSTANT_Utf8); + in.writeUTF("L" + clazz + ";"); + + // 7. Class name (again) + in.writeByte(CONSTANT_Utf8); + in.writeUTF(clazz); + + // 8. Superclass name + in.writeByte(CONSTANT_Utf8); + in.writeUTF(parentClazz); + + // end of constant pool + + // access flags: We want public, ACC_SUPER is always there + in.writeShort(ACC_PUBLIC | ACC_SUPER); + + // this class index in the constant pool + in.writeShort(INDEX_CLASS_THIS); + + // super class index in the constant pool + in.writeShort(INDEX_CLASS_SUPERCLASS); + + // interfaces implemented count (we have none) + in.writeShort(0); + + // fields count (we have none) + in.writeShort(0); + + // methods count (we have one: the default constructor) + in.writeShort(1); + + // default constructor method_info + in.writeShort(ACC_PUBLIC); + in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>) + in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description + in.writeShort(1); // number of attributes: only one, the code + + // code attribute of the default constructor + in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); + in.writeInt(CODE_ATTRIBUTE_LENGTH); // attribute length + in.writeShort(1); // max_stack + in.writeShort(1); // max_locals + in.writeInt(CODE.length); // code length + in.write(CODE); + in.writeShort(0); // exception_table_length = 0 + in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable + + // class attributes + in.writeShort(0); // none. No need to have a source file attribute + + + } catch (IOException e) { + throw new ObjenesisException(e); + } finally { + if(in != null) { + try { + in.close(); + } catch (IOException e) { + throw new ObjenesisException(e); + } + } + } + + return bIn.toByteArray(); + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java b/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java index e1180dc..08c9bc6 100644 --- a/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiator.java @@ -1,48 +1,52 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.gcj;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.objenesis.ObjenesisException;
-
-/**
- * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
- * work on GCJ JVMs. This instantiator will not call any constructors.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class GCJInstantiator extends GCJInstantiatorBase {
- public GCJInstantiator(Class type) {
- super(type);
- }
-
- public Object newInstance() {
- try {
- return newObjectMethod.invoke(dummyStream, new Object[] {type, Object.class});
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.gcj; + +import java.lang.reflect.InvocationTargetException; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to + * work on GCJ JVMs. This instantiator will not call any constructors. + * + * @author Leonardo Mesquita + * @see org.objenesis.instantiator.ObjectInstantiator + */ +@Instantiator(Typology.STANDARD) +public class GCJInstantiator<T> extends GCJInstantiatorBase<T> { + public GCJInstantiator(Class<T> type) { + super(type); + } + + @Override + public T newInstance() { + try { + return type.cast(newObjectMethod.invoke(dummyStream, type, Object.class)); + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(IllegalAccessException e) { + throw new ObjenesisException(e); + } + catch(InvocationTargetException e) { + throw new ObjenesisException(e); + } + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java b/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java index 13bfc90..4477672 100644 --- a/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java +++ b/main/src/main/java/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java @@ -1,69 +1,69 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.gcj;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Base class for GCJ-based instantiators. It initializes reflection access to method
- * ObjectInputStream.newObject, as well as creating a dummy ObjectInputStream to be used as the
- * "this" argument for the method.
- *
- * @author Leonardo Mesquita
- */
-public abstract class GCJInstantiatorBase implements ObjectInstantiator {
- static Method newObjectMethod = null;
- static ObjectInputStream dummyStream;
-
- private static class DummyStream extends ObjectInputStream {
- public DummyStream() throws IOException {
- }
- }
-
- private static void initialize() {
- if(newObjectMethod == null) {
- try {
- newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] {
- Class.class, Class.class});
- newObjectMethod.setAccessible(true);
- dummyStream = new DummyStream();
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(IOException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- protected final Class type;
-
- public GCJInstantiatorBase(Class type) {
- this.type = type;
- initialize();
- }
-
- public abstract Object newInstance();
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.gcj; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; + +/** + * Base class for GCJ-based instantiators. It initializes reflection access to method + * ObjectInputStream.newObject, as well as creating a dummy ObjectInputStream to be used as the + * "this" argument for the method. + * + * @author Leonardo Mesquita + */ +public abstract class GCJInstantiatorBase<T> implements ObjectInstantiator<T> { + static Method newObjectMethod = null; + static ObjectInputStream dummyStream; + + private static class DummyStream extends ObjectInputStream { + public DummyStream() throws IOException { + } + } + + private static void initialize() { + if(newObjectMethod == null) { + try { + newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] { + Class.class, Class.class}); + newObjectMethod.setAccessible(true); + dummyStream = new DummyStream(); + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + catch(IOException e) { + throw new ObjenesisException(e); + } + } + } + + protected final Class<T> type; + + public GCJInstantiatorBase(Class<T> type) { + this.type = type; + initialize(); + } + + public abstract T newInstance(); +} diff --git a/main/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java b/main/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java index e2c1609..c6a4cd6 100644 --- a/main/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java @@ -1,46 +1,50 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.gcj;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.SerializationInstantiatorHelper;
-
-/**
- * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
- * work on GCJ JVMs. This instantiator will create classes in a way compatible with serialization,
- * calling the first non-serializable superclass' no-arg constructor.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class GCJSerializationInstantiator extends GCJInstantiatorBase {
- private Class superType;
-
- public GCJSerializationInstantiator(Class type) {
- super(type);
- this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
- }
-
- public Object newInstance() {
- try {
- return newObjectMethod.invoke(dummyStream, new Object[] {type, superType});
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.gcj; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.SerializationInstantiatorHelper; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to + * work on GCJ JVMs. This instantiator will create classes in a way compatible with serialization, + * calling the first non-serializable superclass' no-arg constructor. + * + * @author Leonardo Mesquita + * @see org.objenesis.instantiator.ObjectInstantiator + */ +@Instantiator(Typology.SERIALIZATION) +public class GCJSerializationInstantiator<T> extends GCJInstantiatorBase<T> { + private Class<? super T> superType; + + public GCJSerializationInstantiator(Class<T> type) { + super(type); + this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type); + } + + @Override + public T newInstance() { + try { + return type.cast(newObjectMethod.invoke(dummyStream, type, superType)); + } + catch(Exception e) { + throw new ObjenesisException(e); + } + } + +} diff --git a/main/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java b/main/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java deleted file mode 100644 index 7db9652..0000000 --- a/main/src/main/java/org/objenesis/instantiator/jrockit/JRockit131Instantiator.java +++ /dev/null @@ -1,89 +0,0 @@ -/**
- * COPYRIGHT & LICENSE
- *
- * This code is Copyright (c) 2006 BEA Systems, inc. It is provided free, as-is and without any warranties for the purpose of
- * inclusion in Objenesis or any other open source project with a FSF approved license, as long as this notice is not
- * removed. There are no limitations on modifying or repackaging the code apart from this.
- *
- * BEA does not guarantee that the code works, and provides no support for it. Use at your own risk.
- *
- * Originally developed by Leonardo Mesquita. Copyright notice added by Henrik Ståhl, BEA JRockit Product Manager.
- *
- */
-package org.objenesis.instantiator.jrockit;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Instantiates a class by making a call to internal JRockit private methods. It is only supposed to
- * work on JRockit 7.0 JVMs, which are compatible with Java API 1.3.1. This instantiator will not
- * call any constructors.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class JRockit131Instantiator implements ObjectInstantiator {
-
- private Constructor mungedConstructor;
-
- private static Method newConstructorForSerializationMethod;
-
- private static void initialize() {
- if(newConstructorForSerializationMethod == null) {
- Class cl;
- try {
- cl = Class.forName("COM.jrockit.reflect.MemberAccess");
- newConstructorForSerializationMethod = cl.getDeclaredMethod(
- "newConstructorForSerialization", new Class[] {Constructor.class, Class.class});
- newConstructorForSerializationMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(ClassNotFoundException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- public JRockit131Instantiator(Class type) {
- initialize();
-
- if(newConstructorForSerializationMethod != null) {
-
- Constructor javaLangObjectConstructor;
-
- try {
- javaLangObjectConstructor = Object.class.getConstructor((Class[]) null);
- }
- catch(NoSuchMethodException e) {
- throw new Error("Cannot find constructor for java.lang.Object!");
- }
-
- try {
- mungedConstructor = (Constructor) newConstructorForSerializationMethod.invoke(null,
- new Object[] {javaLangObjectConstructor, type});
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- }
-
- public Object newInstance() {
- try {
- return mungedConstructor.newInstance((Object[]) null);
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/main/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java b/main/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java deleted file mode 100644 index 9050353..0000000 --- a/main/src/main/java/org/objenesis/instantiator/jrockit/JRockitLegacyInstantiator.java +++ /dev/null @@ -1,70 +0,0 @@ -/**
- * COPYRIGHT & LICENSE
- *
- * This code is Copyright (c) 2006 BEA Systems, inc. It is provided free, as-is and without any warranties for the purpose of
- * inclusion in Objenesis or any other open source project with a FSF approved license, as long as this notice is not
- * removed. There are no limitations on modifying or repackaging the code apart from this.
- *
- * BEA does not guarantee that the code works, and provides no support for it. Use at your own risk.
- *
- * Originally developed by Leonardo Mesquita. Copyright notice added by Henrik Ståhl, BEA JRockit Product Manager.
- *
- */
-
-package org.objenesis.instantiator.jrockit;
-
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Instantiates a class by making a call to internal JRockit private methods. It is only supposed to
- * work on JRockit 1.4.2 JVMs prior to release R25.1. From release R25.1 on, JRockit supports
- * sun.reflect.ReflectionFactory, making this "trick" unnecessary. This instantiator will not call
- * any constructors.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- * @see org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator
- */
-public class JRockitLegacyInstantiator implements ObjectInstantiator {
- private static Method safeAllocObjectMethod = null;
-
- private static void initialize() {
- if(safeAllocObjectMethod == null) {
- Class memSystem;
- try {
- memSystem = Class.forName("jrockit.vm.MemSystem");
- safeAllocObjectMethod = memSystem.getDeclaredMethod("safeAllocObject",
- new Class[] {Class.class});
- safeAllocObjectMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(ClassNotFoundException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- private final Class type;
-
- public JRockitLegacyInstantiator(Class type) {
- initialize();
- this.type = type;
- }
-
- public Object newInstance() {
- try {
- return safeAllocObjectMethod.invoke(null, new Object[] {type});
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/main/src/main/java/org/objenesis/instantiator/perc/PercInstantiator.java b/main/src/main/java/org/objenesis/instantiator/perc/PercInstantiator.java index 9777fcc..7a2f579 100644 --- a/main/src/main/java/org/objenesis/instantiator/perc/PercInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/perc/PercInstantiator.java @@ -1,63 +1,67 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.perc;
-
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Instantiates a class by making a call to internal Perc private methods. It is only supposed to
- * work on Perc JVMs. This instantiator will not call any constructors. The code was provided by
- * Aonix Perc support team.
- *
- * @author Henri Tremblay
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class PercInstantiator implements ObjectInstantiator {
-
- private final Method newInstanceMethod;
-
- private final Object[] typeArgs = new Object[] { null, Boolean.FALSE };
-
- public PercInstantiator(Class type) {
-
- typeArgs[0] = type;
-
- try {
- newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("newInstance",
- new Class[] { Class.class, Boolean.TYPE });
- newInstanceMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-
- public Object newInstance() {
- try {
- return newInstanceMethod.invoke(null, typeArgs);
- } catch (Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.perc; + +import java.io.ObjectInputStream; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiates a class by making a call to internal Perc private methods. It is only supposed to + * work on Perc JVMs. This instantiator will not call any constructors. The code was provided by + * Aonix Perc support team. + * + * @author Henri Tremblay + * @see org.objenesis.instantiator.ObjectInstantiator + */ +@Instantiator(Typology.STANDARD) +public class PercInstantiator<T> implements ObjectInstantiator<T> { + + private final Method newInstanceMethod; + + private final Object[] typeArgs = new Object[] { null, Boolean.FALSE }; + + public PercInstantiator(Class<T> type) { + + typeArgs[0] = type; + + try { + newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, + Boolean.TYPE); + newInstanceMethod.setAccessible(true); + } + catch(RuntimeException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + } + + @SuppressWarnings("unchecked") + public T newInstance() { + try { + return (T) newInstanceMethod.invoke(null, typeArgs); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + +} diff --git a/main/src/main/java/org/objenesis/instantiator/perc/PercSerializationInstantiator.java b/main/src/main/java/org/objenesis/instantiator/perc/PercSerializationInstantiator.java index 8dd8016..b3a140e 100644 --- a/main/src/main/java/org/objenesis/instantiator/perc/PercSerializationInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/perc/PercSerializationInstantiator.java @@ -1,96 +1,100 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.perc;
-
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Instantiates a class by making a call to internal Perc private methods. It is only supposed to
- * work on Perc JVMs. This instantiator will create classes in a way compatible with serialization,
- * calling the first non-serializable superclass' no-arg constructor. <p/> Based on code provided by
- * Aonix but <b>doesn't work right now</b>
- *
- * @author Henri Tremblay
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class PercSerializationInstantiator implements ObjectInstantiator {
-
- private Object[] typeArgs;
-
- private final java.lang.reflect.Method newInstanceMethod;
-
- public PercSerializationInstantiator(Class type) {
-
- // Find the first unserializable parent class
- Class unserializableType = type;
-
- while(Serializable.class.isAssignableFrom(unserializableType)) {
- unserializableType = unserializableType.getSuperclass();
- }
-
- try {
- // Get the special Perc method to call
- Class percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method");
-
- newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct",
- new Class[] {Class.class, Object.class, percMethodClass});
- newInstanceMethod.setAccessible(true);
-
- // Create invoke params
- Class percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass");
- Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass",
- new Class[] {Class.class});
- Object someObject = getPercClassMethod.invoke(null, new Object[] {unserializableType});
- Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod",
- new Class[] {String.class});
- Object percMethod = findMethodMethod.invoke(someObject, new Object[] {"<init>()V"});
-
- typeArgs = new Object[] {unserializableType, type, percMethod};
-
- }
- catch(ClassNotFoundException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- }
-
- public Object newInstance() {
- try {
- return newInstanceMethod.invoke(null, typeArgs);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.perc; + +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * Instantiates a class by making a call to internal Perc private methods. It is only supposed to + * work on Perc JVMs. This instantiator will create classes in a way compatible with serialization, + * calling the first non-serializable superclass' no-arg constructor. + * <p> + * Based on code provided by Aonix but <b>doesn't work right now</b> + * + * @author Henri Tremblay + * @see org.objenesis.instantiator.ObjectInstantiator + */ +@Instantiator(Typology.SERIALIZATION) +public class PercSerializationInstantiator<T> implements ObjectInstantiator<T> { + + private Object[] typeArgs; + + private final Method newInstanceMethod; + + public PercSerializationInstantiator(Class<T> type) { + + // Find the first unserializable parent class + Class<? super T> unserializableType = type; + + while(Serializable.class.isAssignableFrom(unserializableType)) { + unserializableType = unserializableType.getSuperclass(); + } + + try { + // Get the special Perc method to call + Class<?> percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method"); + + newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct", + new Class[] {Class.class, Object.class, percMethodClass}); + newInstanceMethod.setAccessible(true); + + // Create invoke params + Class<?> percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass"); + Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass", Class.class); + Object someObject = getPercClassMethod.invoke(null, unserializableType); + Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod", + new Class[] {String.class}); + Object percMethod = findMethodMethod.invoke(someObject, "<init>()V"); + + typeArgs = new Object[] {unserializableType, type, percMethod}; + + } + catch(ClassNotFoundException e) { + throw new ObjenesisException(e); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + catch(InvocationTargetException e) { + throw new ObjenesisException(e); + } + catch(IllegalAccessException e) { + throw new ObjenesisException(e); + } + } + + @SuppressWarnings("unchecked") + public T newInstance() { + try { + return (T) newInstanceMethod.invoke(null, typeArgs); + } + catch(IllegalAccessException e) { + throw new ObjenesisException(e); + } + catch(InvocationTargetException e) { + throw new ObjenesisException(e); + } + } + +} diff --git a/main/src/main/java/org/objenesis/instantiator/sun/MagicInstantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/MagicInstantiator.java new file mode 100644 index 0000000..4ece96e --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/sun/MagicInstantiator.java @@ -0,0 +1,285 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.sun; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; +import org.objenesis.instantiator.basic.ClassDefinitionUtils; + +import static org.objenesis.instantiator.basic.ClassDefinitionUtils.*; + +/** + * This instantiator will correctly bypass the constructors by instantiating the class using the default + * constructor from Object. It will be allowed to do so by extending {@code MagicAccessorImpl} which prevents + * its children to be verified by the class loader + * + * @author Henri Tremblay + */ +@Instantiator(Typology.STANDARD) +public class MagicInstantiator<T> implements ObjectInstantiator<T> { + + private static final int INDEX_CLASS_THIS = 1; + private static final int INDEX_CLASS_SUPERCLASS = 2; + private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3; + private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4; + private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5; + private static final int INDEX_UTF8_INSTANTIATOR_CLASS = 7; + private static final int INDEX_UTF8_SUPERCLASS = 8; + private static final int INDEX_CLASS_INTERFACE = 9; + private static final int INDEX_UTF8_INTERFACE = 10; + private static final int INDEX_UTF8_NEWINSTANCE_NAME = 11; + private static final int INDEX_UTF8_NEWINSTANCE_DESC = 12; + private static final int INDEX_METHODREF_OBJECT_CONSTRUCTOR = 13; + private static final int INDEX_CLASS_OBJECT = 14; + private static final int INDEX_UTF8_OBJECT = 15; + private static final int INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR = 16; + private static final int INDEX_CLASS_TYPE = 17; + private static final int INDEX_UTF8_TYPE = 18; + + private static int CONSTANT_POOL_COUNT = 19; + + private static final byte[] CONSTRUCTOR_CODE = { OPS_aload_0, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_return}; + private static final int CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH = 12 + CONSTRUCTOR_CODE.length; + + private static final byte[] NEWINSTANCE_CODE = { OPS_new, 0, INDEX_CLASS_TYPE, OPS_dup, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_areturn}; + private static final int NEWINSTANCE_CODE_ATTRIBUTE_LENGTH = 12 + NEWINSTANCE_CODE.length; + + private static final String CONSTRUCTOR_NAME = "<init>"; + private static final String CONSTRUCTOR_DESC = "()V"; + + private ObjectInstantiator<T> instantiator; + + public MagicInstantiator(Class<T> type) { + instantiator = newInstantiatorOf(type); + } + + /** + * Get the underlying instantiator. + * + * {@link MagicInstantiator} is a wrapper around another object + * which implements {@link ObjectInstantiator} interface. + * This method exposes that instantiator. + * + * @return the underlying instantiator + */ + public ObjectInstantiator<T> getInstantiator() { + return instantiator; + } + + private <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { + String suffix = type.getSimpleName(); + String className = getClass().getName() + "$$$" + suffix; + + Class<ObjectInstantiator<T>> clazz = getExistingClass(getClass().getClassLoader(), className); + + if(clazz == null) { + byte[] classBytes = writeExtendingClass(type, className); + + try { + clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader()); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + try { + return clazz.newInstance(); + } catch (InstantiationException e) { + throw new ObjenesisException(e); + } catch (IllegalAccessException e) { + throw new ObjenesisException(e); + } + } + + /** + * Will generate the bytes for a class extending the type passed in parameter. This class will + * only have an empty default constructor + * + * @param type type to extend + * @param className name of the wrapped instantiator class + * @return the byte for the class + * @throws ObjenesisException is something goes wrong + */ + private byte[] writeExtendingClass(Class<?> type, String className) { + String clazz = classNameToInternalClassName(className); + + DataOutputStream in = null; + ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class + try { + in = new DataOutputStream(bIn); + + in.write(MAGIC); + in.write(VERSION); + in.writeShort(CONSTANT_POOL_COUNT); + + // set all the constant pool here + + // 1. class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_INSTANTIATOR_CLASS); + + // 2. super class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_SUPERCLASS); + + // 3. default constructor name + in.writeByte(CONSTANT_Utf8); + in.writeUTF(CONSTRUCTOR_NAME); + + // 4. default constructor description + in.writeByte(CONSTANT_Utf8); + in.writeUTF(CONSTRUCTOR_DESC); + + // 5. Code + in.writeByte(CONSTANT_Utf8); + in.writeUTF("Code"); + + // 6. Class name + in.writeByte(CONSTANT_Utf8); + in.writeUTF("L" + clazz + ";"); + + // 7. Class name (again) + in.writeByte(CONSTANT_Utf8); + in.writeUTF(clazz); + + // 8. Superclass name + in.writeByte(CONSTANT_Utf8); +// in.writeUTF("java/lang/Object"); + in.writeUTF("sun/reflect/MagicAccessorImpl"); + + // 9. ObjectInstantiator interface + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_INTERFACE); + + // 10. ObjectInstantiator name + in.writeByte(CONSTANT_Utf8); + in.writeUTF(ObjectInstantiator.class.getName().replace('.', '/')); + + // 11. newInstance name + in.writeByte(CONSTANT_Utf8); + in.writeUTF("newInstance"); + + // 12. newInstance desc + in.writeByte(CONSTANT_Utf8); + in.writeUTF("()Ljava/lang/Object;"); + + // 13. Methodref to the Object constructor + in.writeByte(CONSTANT_Methodref); + in.writeShort(INDEX_CLASS_OBJECT); + in.writeShort(INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR); + + // 14. Object class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_OBJECT); + + // 15. Object class name + in.writeByte(CONSTANT_Utf8); + in.writeUTF("java/lang/Object"); + + // 16. Default constructor name and type + in.writeByte(CONSTANT_NameAndType); + in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); + in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); + + // 17. Type to instantiate class + in.writeByte(CONSTANT_Class); + in.writeShort(INDEX_UTF8_TYPE); + + // 18. Type to instantiate name + in.writeByte(CONSTANT_Utf8); + in.writeUTF(classNameToInternalClassName(type.getName())); + + // end of constant pool + + // access flags: We want public, ACC_SUPER is always there + in.writeShort(ACC_PUBLIC | ACC_SUPER | ACC_FINAL); + + // this class index in the constant pool + in.writeShort(INDEX_CLASS_THIS); + + // super class index in the constant pool + in.writeShort(INDEX_CLASS_SUPERCLASS); + + // interfaces implemented count (we have none) + in.writeShort(1); + in.writeShort(INDEX_CLASS_INTERFACE); + + // fields count (we have none) + in.writeShort(0); + + // method count (we have two: the default constructor and newInstance) + in.writeShort(2); + + // default constructor method_info + in.writeShort(ACC_PUBLIC); + in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>) + in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description + in.writeShort(1); // number of attributes: only one, the code + + // code attribute of the default constructor + in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); + in.writeInt(CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH); // attribute length + in.writeShort(0); // max_stack + in.writeShort(1); // max_locals + in.writeInt(CONSTRUCTOR_CODE.length); // code length + in.write(CONSTRUCTOR_CODE); + in.writeShort(0); // exception_table_length = 0 + in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable + + // newInstance method_info + in.writeShort(ACC_PUBLIC); + in.writeShort(INDEX_UTF8_NEWINSTANCE_NAME); // index of the method name (newInstance) + in.writeShort(INDEX_UTF8_NEWINSTANCE_DESC); // index of the description + in.writeShort(1); // number of attributes: only one, the code + + // code attribute of newInstance + in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); + in.writeInt(NEWINSTANCE_CODE_ATTRIBUTE_LENGTH); // attribute length + in.writeShort(2); // max_stack + in.writeShort(1); // max_locals + in.writeInt(NEWINSTANCE_CODE.length); // code length + in.write(NEWINSTANCE_CODE); + in.writeShort(0); // exception_table_length = 0 + in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable + + // class attributes + in.writeShort(0); // none. No need to have a source file attribute + + } catch (IOException e) { + throw new ObjenesisException(e); + } finally { + if(in != null) { + try { + in.close(); + } catch (IOException e) { + throw new ObjenesisException(e); + } + } + } + + return bIn.toByteArray(); + } + + public T newInstance() { + return instantiator.newInstance(); + } +} diff --git a/main/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java deleted file mode 100644 index 28c353a..0000000 --- a/main/src/main/java/org/objenesis/instantiator/sun/Sun13Instantiator.java +++ /dev/null @@ -1,49 +0,0 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.sun;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.objenesis.ObjenesisException;
-
-/**
- * Instantiates a class by making a call to internal Sun private methods. It is only supposed to
- * work on Sun HotSpot 1.3 JVM. This instantiator will not call any constructors.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class Sun13Instantiator extends Sun13InstantiatorBase {
- public Sun13Instantiator(Class type) {
- super(type);
- }
-
- public Object newInstance() {
- try {
- return allocateNewObjectMethod.invoke(null, new Object[] {type, Object.class});
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/main/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java b/main/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java deleted file mode 100644 index 13073a1..0000000 --- a/main/src/main/java/org/objenesis/instantiator/sun/Sun13InstantiatorBase.java +++ /dev/null @@ -1,58 +0,0 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.sun;
-
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Base class for Sun 1.3 based instantiators. It initializes reflection access to static method
- * ObjectInputStream.allocateNewObject.
- *
- * @author Leonardo Mesquita
- */
-public abstract class Sun13InstantiatorBase implements ObjectInstantiator {
- static Method allocateNewObjectMethod = null;
-
- private static void initialize() {
- if(allocateNewObjectMethod == null) {
- try {
- allocateNewObjectMethod = ObjectInputStream.class.getDeclaredMethod(
- "allocateNewObject", new Class[] {Class.class, Class.class});
- allocateNewObjectMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- protected final Class type;
-
- public Sun13InstantiatorBase(Class type) {
- this.type = type;
- initialize();
- }
-
- public abstract Object newInstance();
-
-}
diff --git a/main/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java deleted file mode 100644 index 9669e57..0000000 --- a/main/src/main/java/org/objenesis/instantiator/sun/Sun13SerializationInstantiator.java +++ /dev/null @@ -1,46 +0,0 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator.sun;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.SerializationInstantiatorHelper;
-
-/**
- * Instantiates a class by making a call to internal Sun private methods. It is only supposed to
- * work on Sun HotSpot 1.3 JVM. This instantiator will create classes in a way compatible with
- * serialization, calling the first non-serializable superclass' no-arg constructor.
- *
- * @author Leonardo Mesquita
- * @see org.objenesis.instantiator.ObjectInstantiator
- */
-public class Sun13SerializationInstantiator extends Sun13InstantiatorBase {
- private final Class superType;
-
- public Sun13SerializationInstantiator(Class type) {
- super(type);
- this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
- }
-
- public Object newInstance() {
- try {
- return allocateNewObjectMethod.invoke(null, new Object[] {type, superType});
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java index 5717b72..4396385 100644 --- a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java +++ b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.objenesis.instantiator.sun; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -29,18 +28,21 @@ import org.objenesis.instantiator.ObjectInstantiator; * * @author Henri Tremblay */ +@SuppressWarnings("restriction") class SunReflectionFactoryHelper { - public static Constructor newConstructorForSerialization(Class type, Constructor constructor) { - Class reflectionFactoryClass = getReflectionFactoryClass(); + @SuppressWarnings("unchecked") + public static <T> Constructor<T> newConstructorForSerialization(Class<T> type, + Constructor<?> constructor) { + Class<?> reflectionFactoryClass = getReflectionFactoryClass(); Object reflectionFactory = createReflectionFactory(reflectionFactoryClass); Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod( reflectionFactoryClass); try { - return (Constructor) newConstructorForSerializationMethod.invoke( - reflectionFactory, new Object[] {type, constructor}); + return (Constructor<T>) newConstructorForSerializationMethod.invoke( + reflectionFactory, type, constructor); } catch(IllegalArgumentException e) { throw new ObjenesisException(e); @@ -53,7 +55,7 @@ class SunReflectionFactoryHelper { } } - private static Class getReflectionFactoryClass() { + private static Class<?> getReflectionFactoryClass() { try { return Class.forName("sun.reflect.ReflectionFactory"); } @@ -62,11 +64,11 @@ class SunReflectionFactoryHelper { } } - private static Object createReflectionFactory(Class reflectionFactoryClass) { + private static Object createReflectionFactory(Class<?> reflectionFactoryClass) { try { Method method = reflectionFactoryClass.getDeclaredMethod( - "getReflectionFactory", new Class[] {}); - return method.invoke(null, new Object[] {}); + "getReflectionFactory"); + return method.invoke(null); } catch(NoSuchMethodException e) { throw new ObjenesisException(e); @@ -82,10 +84,10 @@ class SunReflectionFactoryHelper { } } - private static Method getNewConstructorForSerializationMethod(Class reflectionFactoryClass) { + private static Method getNewConstructorForSerializationMethod(Class<?> reflectionFactoryClass) { try { return reflectionFactoryClass.getDeclaredMethod( - "newConstructorForSerialization", new Class[] {Class.class, Constructor.class}); + "newConstructorForSerialization", Class.class, Constructor.class); } catch(NoSuchMethodException e) { throw new ObjenesisException(e); diff --git a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java index fa30448..f1ae3a7 100644 --- a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,28 +19,31 @@ import java.lang.reflect.Constructor; import org.objenesis.ObjenesisException; import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; /** * Instantiates an object, WITHOUT calling it's constructor, using internal * sun.reflect.ReflectionFactory - a class only available on JDK's that use Sun's 1.4 (or later) * Java implementation. This is the best way to instantiate an object without any side effects * caused by the constructor - however it is not available on every platform. - * + * * @author Joe Walnes * @see ObjectInstantiator */ -public class SunReflectionFactoryInstantiator implements ObjectInstantiator { +@Instantiator(Typology.STANDARD) +public class SunReflectionFactoryInstantiator<T> implements ObjectInstantiator<T> { - private final Constructor mungedConstructor; + private final Constructor<T> mungedConstructor; - public SunReflectionFactoryInstantiator(Class type) { - Constructor javaLangObjectConstructor = getJavaLangObjectConstructor(); + public SunReflectionFactoryInstantiator(Class<T> type) { + Constructor<Object> javaLangObjectConstructor = getJavaLangObjectConstructor(); mungedConstructor = SunReflectionFactoryHelper.newConstructorForSerialization( type, javaLangObjectConstructor); mungedConstructor.setAccessible(true); } - public Object newInstance() { + public T newInstance() { try { return mungedConstructor.newInstance((Object[]) null); } @@ -49,7 +52,7 @@ public class SunReflectionFactoryInstantiator implements ObjectInstantiator { } } - private static Constructor getJavaLangObjectConstructor() { + private static Constructor<Object> getJavaLangObjectConstructor() { try { return Object.class.getConstructor((Class[]) null); } diff --git a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java index e6bb2c8..21e024a 100644 --- a/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java +++ b/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ import java.lang.reflect.Constructor; import org.objenesis.ObjenesisException; import org.objenesis.instantiator.ObjectInstantiator; import org.objenesis.instantiator.SerializationInstantiatorHelper; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; /** * Instantiates an object using internal sun.reflect.ReflectionFactory - a class only available on @@ -28,24 +30,26 @@ import org.objenesis.instantiator.SerializationInstantiatorHelper; * a way compatible with serialization, calling the first non-serializable superclass' no-arg * constructor. This is the best way to instantiate an object without any side effects caused by the * constructor - however it is not available on every platform. - * + * * @author Leonardo Mesquita * @see ObjectInstantiator */ -public class SunReflectionFactorySerializationInstantiator implements ObjectInstantiator { +@Instantiator(Typology.SERIALIZATION) +public class SunReflectionFactorySerializationInstantiator<T> implements ObjectInstantiator<T> { + + private final Constructor<T> mungedConstructor; - private final Constructor mungedConstructor; + public SunReflectionFactorySerializationInstantiator(Class<T> type) { + Class<? super T> nonSerializableAncestor = SerializationInstantiatorHelper + .getNonSerializableSuperClass(type); - public SunReflectionFactorySerializationInstantiator(Class type) { - Class nonSerializableAncestor = SerializationInstantiatorHelper.getNonSerializableSuperClass(type); - - Constructor nonSerializableAncestorConstructor; + Constructor<? super T> nonSerializableAncestorConstructor; try { nonSerializableAncestorConstructor = nonSerializableAncestor .getConstructor((Class[]) null); } catch(NoSuchMethodException e) { - throw new ObjenesisException(new NotSerializableException(type+" has no suitable superclass constructor")); + throw new ObjenesisException(new NotSerializableException(type+" has no suitable superclass constructor")); } mungedConstructor = SunReflectionFactoryHelper.newConstructorForSerialization( @@ -53,7 +57,7 @@ public class SunReflectionFactorySerializationInstantiator implements ObjectInst mungedConstructor.setAccessible(true); } - public Object newInstance() { + public T newInstance() { try { return mungedConstructor.newInstance((Object[]) null); } diff --git a/main/src/main/java/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java b/main/src/main/java/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java new file mode 100644 index 0000000..6ccb070 --- /dev/null +++ b/main/src/main/java/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java @@ -0,0 +1,66 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.sun; + +import sun.misc.Unsafe; +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +import java.lang.reflect.Field; + +/** + * Instantiates an object, WITHOUT calling it's constructor, using + * sun.misc.Unsafe.allocateInstance(). Unsafe and its methods are implemented by most + * modern JVMs. + * + * @author Henri Tremblay + * @see ObjectInstantiator + */ +@SuppressWarnings("restriction") +@Instantiator(Typology.STANDARD) +public class UnsafeFactoryInstantiator<T> implements ObjectInstantiator<T> { + + private static Unsafe unsafe; + private final Class<T> type; + + public UnsafeFactoryInstantiator(Class<T> type) { + if (unsafe == null) { + Field f; + try { + f = Unsafe.class.getDeclaredField("theUnsafe"); + } catch (NoSuchFieldException e) { + throw new ObjenesisException(e); + } + f.setAccessible(true); + try { + unsafe = (Unsafe) f.get(null); + } catch (IllegalAccessException e) { + throw new ObjenesisException(e); + } + } + this.type = type; + } + + public T newInstance() { + try { + return type.cast(unsafe.allocateInstance(type)); + } catch (InstantiationException e) { + throw new ObjenesisException(e); + } + } +} diff --git a/main/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java b/main/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java index 6161576..909420a 100644 --- a/main/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java +++ b/main/src/main/java/org/objenesis/strategy/BaseInstantiatorStrategy.java @@ -1,54 +1,25 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.strategy;
-
-/**
- * Base {@link InstantiatorStrategy} class basically containing helpful constant to sort out JVMs.
- *
- * @author Henri Tremblay
- */
-public abstract class BaseInstantiatorStrategy implements InstantiatorStrategy {
-
- /** JVM_NAME prefix for JRockit */
- protected static final String JROCKIT = "BEA";
-
- /** JVM_NAME prefix for GCJ */
- protected static final String GNU = "GNU libgcj";
-
- /** JVM_NAME prefix for Sun Java HotSpot */
- protected static final String SUN = "Java HotSpot";
-
- /** JVM_NAME prefix for Aonix PERC */
- protected static final String PERC = "PERC";
-
- /** JVM_NAME prefix for Dalvik/Android */
- protected static final String DALVIK = "Dalvik";
-
- /** JVM version */
- protected static final String VM_VERSION = System.getProperty("java.runtime.version");
-
- /** JVM version */
- protected static final String VM_INFO = System.getProperty("java.vm.info");
-
- /** Vendor version */
- protected static final String VENDOR_VERSION = System.getProperty("java.vm.version");
-
- /** Vendor name */
- protected static final String VENDOR = System.getProperty("java.vm.vendor");
-
- /** JVM name */
- protected static final String JVM_NAME = System.getProperty("java.vm.name");
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +/** + * Base {@link InstantiatorStrategy} class basically. Only implements {@link InstantiatorStrategy} + * + * @author Henri Tremblay + */ +public abstract class BaseInstantiatorStrategy implements InstantiatorStrategy { + +} diff --git a/main/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java b/main/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java index dfaa84e..657cb2a 100644 --- a/main/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java +++ b/main/src/main/java/org/objenesis/strategy/InstantiatorStrategy.java @@ -1,34 +1,35 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.strategy;
-
-import org.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Defines a strategy to determine the best instantiator for a class.
- *
- * @author Henri Tremblay
- */
-public interface InstantiatorStrategy {
-
- /**
- * Create a dedicated instantiator for the given class
- *
- * @param type Class that will be instantiate
- * @return Dedicated instantiator
- */
- ObjectInstantiator newInstantiatorOf(Class type);
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +import org.objenesis.instantiator.ObjectInstantiator; + +/** + * Defines a strategy to determine the best instantiator for a class. + * + * @author Henri Tremblay + */ +public interface InstantiatorStrategy { + + /** + * Create a dedicated instantiator for the given class + * + * @param <T> Type to instantiate + * @param type Class that will be instantiated + * @return Dedicated instantiator + */ + <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type); +} diff --git a/main/src/main/java/org/objenesis/strategy/PlatformDescription.java b/main/src/main/java/org/objenesis/strategy/PlatformDescription.java new file mode 100644 index 0000000..8024567 --- /dev/null +++ b/main/src/main/java/org/objenesis/strategy/PlatformDescription.java @@ -0,0 +1,198 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +import org.objenesis.ObjenesisException; + +import java.lang.reflect.Field; + +/** + * List of constants describing the currently used platform. + * + * @author Henri Tremblay + */ +public final class PlatformDescription { + + /** JVM_NAME prefix for JRockit */ + public static final String JROCKIT = "BEA"; + + /** JVM_NAME prefix for GCJ */ + public static final String GNU = "GNU libgcj"; + + /** JVM_NAME prefix for Java HotSpot */ + public static final String HOTSPOT = "Java HotSpot"; + + /** + * JVM_NAME prefix for Java HotSpot + * + * @deprecated Use {@link #HOTSPOT} instead + */ + @Deprecated + public static final String SUN = HOTSPOT; + + /** JVM_NAME prefix for the OpenJDK */ + public static final String OPENJDK = "OpenJDK"; + + /** JVM_NAME prefix for Aonix PERC */ + public static final String PERC = "PERC"; + + /** JVM_NAME prefix for Dalvik/Android */ + public static final String DALVIK = "Dalvik"; + + /** Java specification version */ + public static final String SPECIFICATION_VERSION = System + .getProperty("java.specification.version"); + + /** JVM version */ + public static final String VM_VERSION = System.getProperty("java.runtime.version"); + + /** JVM version */ + public static final String VM_INFO = System.getProperty("java.vm.info"); + + /** VM vendor version */ + public static final String VENDOR_VERSION = System.getProperty("java.vm.version"); + + /** VM vendor name */ + public static final String VENDOR = System.getProperty("java.vm.vendor"); + + /** JVM name */ + public static final String JVM_NAME = System.getProperty("java.vm.name"); + + /** Android version. Will be 0 for none android platform */ + public static final int ANDROID_VERSION = getAndroidVersion(); + + /** Flag telling if this version of Android is based on the OpenJDK */ + public static final boolean IS_ANDROID_OPENJDK = getIsAndroidOpenJDK(); + + /** Google App Engine version or null is we are not on GAE */ + public static final String GAE_VERSION = getGaeRuntimeVersion(); + + /** + * Describes the platform. Outputs Java version and vendor. + * + * @return Description of the current platform + */ + public static String describePlatform() { + String desc = "Java " + SPECIFICATION_VERSION + " (" + + "VM vendor name=\"" + VENDOR + "\", " + + "VM vendor version=" + VENDOR_VERSION + ", " + + "JVM name=\"" + JVM_NAME + "\", " + + "JVM version=" + VM_VERSION + ", " + + "JVM info=" + VM_INFO; + + // Add the API level is it's an Android platform + int androidVersion = ANDROID_VERSION; + if(androidVersion != 0) { + desc += ", API level=" + ANDROID_VERSION; + } + desc += ")"; + + return desc; + } + + /** + * Check if the current JVM is of the type passed in parameter. Normally, this will be a constant + * from this class. We basically do + * <code>System.getProperty("java.vm.name").startWith(name)</code>. + * + * @param name jvm name we are looking for + * @return if it's the requested JVM + */ + public static boolean isThisJVM(String name) { + return JVM_NAME.startsWith(name); + } + + /** + * Check if this JVM is an Android JVM based on OpenJDK. + * + * @return if it's an Android version based on the OpenJDK. Will return false if this JVM isn't an Android JVM at all + */ + public static boolean isAndroidOpenJDK() { + return IS_ANDROID_OPENJDK; + } + + private static boolean getIsAndroidOpenJDK() { + if(getAndroidVersion() == 0) { + return false; // Not android at all + } + // Sadly, Android N is still API 23. So we can't base ourselves on the API level to know if it is an OpenJDK + // version or not + String bootClasspath = System.getProperty("java.boot.class.path"); + return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar"); + } + + public static boolean isGoogleAppEngine() { + return GAE_VERSION != null; + } + + private static String getGaeRuntimeVersion() { + return System.getProperty("com.google.appengine.runtime.version"); + } + + private static int getAndroidVersion() { + if(!isThisJVM(DALVIK)) { + return 0; + } + return getAndroidVersion0(); + } + + private static int getAndroidVersion0() { + Class<?> clazz; + try { + clazz = Class.forName("android.os.Build$VERSION"); + } + catch(ClassNotFoundException e) { + throw new ObjenesisException(e); + } + Field field; + try { + field = clazz.getField("SDK_INT"); + } + catch(NoSuchFieldException e) { + // Might be a really old API (before 4), go for SDK + return getOldAndroidVersion(clazz); + } + int version; + try { + version = (Integer) field.get(null); + } + catch(IllegalAccessException e) { + throw new RuntimeException(e); + } + return version; + } + + private static int getOldAndroidVersion(Class<?> versionClass) { + Field field; + try { + field = versionClass.getField("SDK"); + } + catch(NoSuchFieldException e) { + throw new ObjenesisException(e); + } + String version; + try { + version = (String) field.get(null); + } + catch(IllegalAccessException e) { + throw new RuntimeException(e); + } + return Integer.parseInt(version); + } + + private PlatformDescription() { + } +} diff --git a/main/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java b/main/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java index 1af2d3e..594598e 100644 --- a/main/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java +++ b/main/src/main/java/org/objenesis/strategy/SerializingInstantiatorStrategy.java @@ -1,75 +1,86 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.strategy;
-
-import java.io.NotSerializableException;
-import java.io.Serializable;
-
-import org.objenesis.ObjenesisException;
-import org.objenesis.instantiator.ObjectInstantiator;
-import org.objenesis.instantiator.android.AndroidSerializationInstantiator;
-import org.objenesis.instantiator.basic.ObjectStreamClassInstantiator;
-import org.objenesis.instantiator.gcj.GCJSerializationInstantiator;
-import org.objenesis.instantiator.perc.PercSerializationInstantiator;
-import org.objenesis.instantiator.sun.Sun13SerializationInstantiator;
-
-/**
- * Guess the best serializing instantiator for a given class. The returned instantiator will
- * instantiate classes like the genuine java serialization framework (the constructor of the first
- * not serializable class will be called). Currently, the selection doesn't depend on the class. It
- * relies on the
- * <ul>
- * <li>JVM version</li>
- * <li>JVM vendor</li>
- * <li>JVM vendor version</li>
- * </ul>
- * However, instantiators are stateful and so dedicated to their class.
- *
- * @author Henri Tremblay
- * @see ObjectInstantiator
- */
-public class SerializingInstantiatorStrategy extends BaseInstantiatorStrategy {
-
- /**
- * Return an {@link ObjectInstantiator} allowing to create instance following the java
- * serialization framework specifications.
- *
- * @param type Class to instantiate
- * @return The ObjectInstantiator for the class
- */
- public ObjectInstantiator newInstantiatorOf(Class type) {
- if(!Serializable.class.isAssignableFrom(type)) {
- throw new ObjenesisException(new NotSerializableException(type+" not serializable"));
- }
- if(JVM_NAME.startsWith(SUN)) {
- if(VM_VERSION.startsWith("1.3")) {
- return new Sun13SerializationInstantiator(type);
- }
- }
- else if(JVM_NAME.startsWith(DALVIK)) {
- return new AndroidSerializationInstantiator(type);
- }
- else if(JVM_NAME.startsWith(GNU)) {
- return new GCJSerializationInstantiator(type);
- }
- else if(JVM_NAME.startsWith(PERC)) {
- return new PercSerializationInstantiator(type);
- }
-
- return new ObjectStreamClassInstantiator(type);
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.instantiator.android.AndroidSerializationInstantiator; +import org.objenesis.instantiator.basic.ObjectInputStreamInstantiator; +import org.objenesis.instantiator.basic.ObjectStreamClassInstantiator; +import org.objenesis.instantiator.gcj.GCJSerializationInstantiator; +import org.objenesis.instantiator.perc.PercSerializationInstantiator; +import org.objenesis.instantiator.sun.SunReflectionFactorySerializationInstantiator; + +import java.io.NotSerializableException; +import java.io.Serializable; + +import static org.objenesis.strategy.PlatformDescription.*; + +/** + * Guess the best serializing instantiator for a given class. The returned instantiator will + * instantiate classes like the genuine java serialization framework (the constructor of the first + * not serializable class will be called). Currently, the selection doesn't depend on the class. It + * relies on the + * <ul> + * <li>JVM version</li> + * <li>JVM vendor</li> + * <li>JVM vendor version</li> + * </ul> + * However, instantiators are stateful and so dedicated to their class. + * + * @author Henri Tremblay + * @see ObjectInstantiator + */ +public class SerializingInstantiatorStrategy extends BaseInstantiatorStrategy { + + /** + * Return an {@link ObjectInstantiator} allowing to create instance following the java + * serialization framework specifications. + * + * @param type Class to instantiate + * @return The ObjectInstantiator for the class + */ + public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { + if(!Serializable.class.isAssignableFrom(type)) { + throw new ObjenesisException(new NotSerializableException(type+" not serializable")); + } + if(JVM_NAME.startsWith(HOTSPOT) || PlatformDescription.isThisJVM(OPENJDK)) { + if(isGoogleAppEngine()) { + return new ObjectInputStreamInstantiator<T>(type); + } + // ObjectStreamClassInstantiator uses setAccessible which isn't supported on JDK9 + if(PlatformDescription.SPECIFICATION_VERSION.equals("9")) { + return new SunReflectionFactorySerializationInstantiator<T>(type); + } + return new ObjectStreamClassInstantiator<T>(type); + } + else if(JVM_NAME.startsWith(DALVIK)) { + if(PlatformDescription.isAndroidOpenJDK()) { + return new ObjectStreamClassInstantiator<T>(type); + } + return new AndroidSerializationInstantiator<T>(type); + } + else if(JVM_NAME.startsWith(GNU)) { + return new GCJSerializationInstantiator<T>(type); + } + else if(JVM_NAME.startsWith(PERC)) { + return new PercSerializationInstantiator<T>(type); + } + + return new ObjectStreamClassInstantiator<T>(type); + } + +} diff --git a/main/src/main/java/org/objenesis/strategy/SingleInstantiatorStrategy.java b/main/src/main/java/org/objenesis/strategy/SingleInstantiatorStrategy.java new file mode 100644 index 0000000..b0e5b80 --- /dev/null +++ b/main/src/main/java/org/objenesis/strategy/SingleInstantiatorStrategy.java @@ -0,0 +1,70 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +import org.objenesis.ObjenesisException; +import org.objenesis.instantiator.ObjectInstantiator; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/** + * Strategy returning only one instantiator type. Useful if you know on which JVM Objenesis + * will be used and want to specify it explicitly. + * + * @author Henri Tremblay + */ +public class SingleInstantiatorStrategy implements InstantiatorStrategy { + + private Constructor<?> constructor; + + /** + * Create a strategy that will return always the same instantiator type. We assume this instantiator + * has one constructor taking the class to instantiate in parameter. + * + * @param <T> the type we want to instantiate + * @param instantiator the instantiator type + */ + public <T extends ObjectInstantiator<?>> SingleInstantiatorStrategy(Class<T> instantiator) { + try { + constructor = instantiator.getConstructor(Class.class); + } + catch(NoSuchMethodException e) { + throw new ObjenesisException(e); + } + } + + /** + * Return an instantiator for the wanted type and of the one and only type of instantiator returned by this + * class. + * + * @param <T> the type we want to instantiate + * @param type Class to instantiate + * @return The ObjectInstantiator for the class + */ + @SuppressWarnings("unchecked") + public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { + try { + return (ObjectInstantiator<T>) constructor.newInstance(type); + } catch (InstantiationException e) { + throw new ObjenesisException(e); + } catch (IllegalAccessException e) { + throw new ObjenesisException(e); + } catch (InvocationTargetException e) { + throw new ObjenesisException(e); + } + } +} diff --git a/main/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java b/main/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java index 2b71d9a..4475d53 100644 --- a/main/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java +++ b/main/src/main/java/org/objenesis/strategy/StdInstantiatorStrategy.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,19 @@ package org.objenesis.strategy; import org.objenesis.instantiator.ObjectInstantiator; -import org.objenesis.instantiator.android.AndroidInstantiator; +import org.objenesis.instantiator.android.Android10Instantiator; +import org.objenesis.instantiator.android.Android17Instantiator; +import org.objenesis.instantiator.android.Android18Instantiator; +import org.objenesis.instantiator.basic.AccessibleInstantiator; +import org.objenesis.instantiator.basic.ObjectInputStreamInstantiator; import org.objenesis.instantiator.gcj.GCJInstantiator; -import org.objenesis.instantiator.jrockit.JRockit131Instantiator; -import org.objenesis.instantiator.jrockit.JRockitLegacyInstantiator; import org.objenesis.instantiator.perc.PercInstantiator; -import org.objenesis.instantiator.sun.Sun13Instantiator; import org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator; +import org.objenesis.instantiator.sun.UnsafeFactoryInstantiator; + +import java.io.Serializable; + +import static org.objenesis.strategy.PlatformDescription.*; /** * Guess the best instantiator for a given class. The instantiator will instantiate the class @@ -34,7 +40,7 @@ import org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator; * <li>JVM vendor version</li> * </ul> * However, instantiators are stateful and so dedicated to their class. - * + * * @author Henri Tremblay * @see ObjectInstantiator */ @@ -43,49 +49,52 @@ public class StdInstantiatorStrategy extends BaseInstantiatorStrategy { /** * Return an {@link ObjectInstantiator} allowing to create instance without any constructor being * called. - * + * * @param type Class to instantiate * @return The ObjectInstantiator for the class */ - public ObjectInstantiator newInstantiatorOf(Class type) { + public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { - if(JVM_NAME.startsWith(SUN)) { - if(VM_VERSION.startsWith("1.3")) { - return new Sun13Instantiator(type); + if(PlatformDescription.isThisJVM(HOTSPOT) || PlatformDescription.isThisJVM(OPENJDK)) { + if(PlatformDescription.isGoogleAppEngine()) { + if(Serializable.class.isAssignableFrom(type)) { + return new ObjectInputStreamInstantiator<T>(type); + } + return new AccessibleInstantiator<T>(type); } + // The UnsafeFactoryInstantiator would also work. But according to benchmarks, it is 2.5 + // times slower. So I prefer to use this one + return new SunReflectionFactoryInstantiator<T>(type); } - else if(JVM_NAME.startsWith(JROCKIT)) { - if(VM_VERSION.startsWith("1.3")) { - return new JRockit131Instantiator(type); + else if(PlatformDescription.isThisJVM(DALVIK)) { + if(PlatformDescription.isAndroidOpenJDK()) { + // Starting at Android N which is based on OpenJDK + return new UnsafeFactoryInstantiator<T>(type); } - else if(VM_VERSION.startsWith("1.4")) { - // JRockit vendor version will be RXX where XX is the version - // Versions prior to 26 need special handling - // From R26 on, java.vm.version starts with R - if(!VENDOR_VERSION.startsWith("R")) { - // On R25.1 and R25.2, ReflectionFactory should work. Otherwise, we must use the - // Legacy instantiator. - if(VM_INFO == null || !VM_INFO.startsWith("R25.1") || !VM_INFO.startsWith("R25.2")) { - return new JRockitLegacyInstantiator(type); - } - } + if(ANDROID_VERSION <= 10) { + // Android 2.3 Gingerbread and lower + return new Android10Instantiator<T>(type); + } + if(ANDROID_VERSION <= 17) { + // Android 3.0 Honeycomb to 4.2 Jelly Bean + return new Android17Instantiator<T>(type); } + // Android 4.3 until Android N + return new Android18Instantiator<T>(type); } - else if(JVM_NAME.startsWith(DALVIK)) { - return new AndroidInstantiator(type); + else if(PlatformDescription.isThisJVM(JROCKIT)) { + // JRockit is compliant with HotSpot + return new SunReflectionFactoryInstantiator<T>(type); } - else if(JVM_NAME.startsWith(GNU)) { - return new GCJInstantiator(type); + else if(PlatformDescription.isThisJVM(GNU)) { + return new GCJInstantiator<T>(type); } - else if(JVM_NAME.startsWith(PERC)) { - return new PercInstantiator(type); + else if(PlatformDescription.isThisJVM(PERC)) { + return new PercInstantiator<T>(type); } - // Fallback instantiator, should work with: - // - Java Hotspot version 1.4 and higher - // - JRockit 1.4-R26 and higher - // - IBM and Hitachi JVMs - // ... might works for others so we just give it a try - return new SunReflectionFactoryInstantiator(type); + // Fallback instantiator, should work with most modern JVM + return new UnsafeFactoryInstantiator<T>(type); + } } diff --git a/main/src/main/java/org/objenesis/instantiator/NullInstantiator.java b/main/src/test/java/android/os/Build.java index ab2a44f..c4b3107 100644 --- a/main/src/main/java/org/objenesis/instantiator/NullInstantiator.java +++ b/main/src/test/java/android/os/Build.java @@ -1,31 +1,29 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.instantiator;
-
-/**
- * The instantiator that always return a null instance
- *
- * @author Henri Tremblay
- */
-public class NullInstantiator implements ObjectInstantiator {
-
- /**
- * @return Always null
- */
- public Object newInstance() {
- return null;
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 android.os; + +/** + * Mimics the real Android class. Used for testing + * + * @author Henri Tremblay + */ +public class Build { + + public static class VERSION { + public static final int SDK_INT = 42; + public static final String SDK = "42"; + } +} diff --git a/main/src/test/java/org/objenesis/ClassReader.java b/main/src/test/java/org/objenesis/ClassReader.java new file mode 100644 index 0000000..21dbb1d --- /dev/null +++ b/main/src/test/java/org/objenesis/ClassReader.java @@ -0,0 +1,340 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +import static org.junit.Assert.*; +import static org.objenesis.instantiator.basic.ClassDefinitionUtils.*; + +/** + * @author Henri Tremblay + */ +public class ClassReader { + + byte[] buffer = new byte[256]; + Object[] constant_pool; + + public static void main(String[] args) throws IOException { + if(args.length != 1) { + System.out.println("Usage: ClassReader (path_to_the_class_file|class:complete_class_name)"); + } + + ClassReader reader = new ClassReader(); + reader.readClass(args[0]); + } + + static class CONSTANT_Utf8_info { + // int length; u2 is read by readUTF + String bytes; + + CONSTANT_Utf8_info(DataInputStream in) throws IOException { + bytes = in.readUTF(); + } + + @Override + public String toString() { + return "CONSTANT_Utf8_info{" + + "bytes='" + bytes + '\'' + + '}'; + } + } + + static class CONSTANT_Methodref_info { + int class_index; // u2 + int name_and_type_index; // u2 + + CONSTANT_Methodref_info(DataInputStream in) throws IOException { + class_index = in.readUnsignedShort(); + name_and_type_index = in.readUnsignedShort(); + } + + @Override + public String toString() { + return "CONSTANT_Methodref_info{" + + "class_index=" + class_index + + ", name_and_type_index=" + name_and_type_index + + '}'; + } + } + + static class CONSTANT_Class_info { + int name_index; // u2 + + public CONSTANT_Class_info(DataInputStream in) throws IOException{ + name_index = in.readUnsignedShort(); + } + + @Override + public String toString() { + return "CONSTANT_Class_info{" + + "name_index=" + name_index + + '}'; + } + } + + static class CONSTANT_NameAndType_info { + int name_index; // u2 + int descriptor_index; // u2 + + public CONSTANT_NameAndType_info(DataInputStream in) throws IOException{ + name_index = in.readUnsignedShort(); + descriptor_index = in.readUnsignedShort(); + } + + @Override + public String toString() { + return "CONSTANT_NameAndType_info{" + + "name_index=" + name_index + + ", descriptor_index=" + descriptor_index + + '}'; + } + } + + class method_info { + int access_flags; // u2 + int name_index; + int descriptor_index; + int attributes_count; + attribute_info[] attributes; + + public method_info(DataInputStream in) throws IOException{ + access_flags = in.readUnsignedShort(); + name_index = in.readUnsignedShort(); + descriptor_index = in.readUnsignedShort(); + attributes_count = in.readUnsignedShort(); + attributes = new attribute_info[attributes_count]; + + for (int i = 0; i < attributes_count; i++) { + attributes[i] = new attribute_info(in); + } + } + + @Override + public String toString() { + return "method_info{" + + "access_flags=" + access_flags + + ", name_index=" + name_index + + ", descriptor_index=" + descriptor_index + + ", attributes_count=" + attributes_count + + '}'; + } + } + + class attribute_info { + int attribute_name_index; // u2 + int attribute_length; // u4 + Object info; + + public attribute_info(DataInputStream in) throws IOException{ + attribute_name_index = in.readUnsignedShort(); + attribute_length = in.readInt(); + + String attribute_name = ((CONSTANT_Utf8_info) constant_pool[attribute_name_index]).bytes; + + System.out.println(this + " " + attribute_name); + + if("Code".equals(attribute_name)) { + info = new Code_attribute(in); + } + else if("SourceFile".equals(attribute_name)) { + assertEquals(2, attribute_length); // always 2 + info = new SourceFile_attribute(in); + } + else if("LineNumberTable".equals(attribute_name)) { + // I don't care about that (only used for debugging) so I will skip + System.out.println("Attribute LineNumberTable skipped"); + in.read(buffer, 0, attribute_length); + } + else if("LocalVariableTable".equals(attribute_name)) { + // I don't care about that (only used for debugging) so I will skip + System.out.println("Attribute LocalVariableTable skipped"); + in.read(buffer, 0, attribute_length); + } + else { + fail("Unknown attribute: " + attribute_name); + } + + System.out.println("\t" + info); + } + + @Override + public String toString() { + return "attribute_info{" + + "attribute_name_index=" + attribute_name_index + + ", attribute_length=" + attribute_length + + '}'; + } + } + + class Code_attribute { + int max_stack; // u2 + int max_locals; // u2 + int code_length; // u4 + byte[] code; // length of code_length + int exception_table_length; // u2 if will be 0, so we will skip the exception_table + int attributes_count; // u2 + attribute_info[] attributes; + + Code_attribute(DataInputStream in) throws IOException { + max_stack = in.readUnsignedShort(); + max_locals = in.readUnsignedShort(); + code_length = in.readInt(); + code = new byte[code_length]; + in.read(code); + exception_table_length = in.readUnsignedShort(); + attributes_count = in.readUnsignedShort(); + attributes = new attribute_info[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = new attribute_info(in); + } + } + + @Override + public String toString() { + return "Code_attribute{" + + "max_stack=" + max_stack + + ", max_locals=" + max_locals + + ", code_length=" + code_length + + ", code=" + Arrays.toString(code) + + ", exception_table_length=" + exception_table_length + + ", attributes_count=" + attributes_count + + '}'; + } + } + + static class SourceFile_attribute { + int sourcefile_index; + + SourceFile_attribute(DataInputStream in) throws IOException { + sourcefile_index = in.readUnsignedShort(); + } + + @Override + public String toString() { + return "SourceFile_attribute{" + + "sourcefile_index=" + sourcefile_index + + '}'; + } + } + + public void readClass(String classPath) throws IOException { + InputStream iin; + if(classPath.startsWith("classpath:")) { + String className = classPath.substring("classpath:".length()); + String resourceName = classNameToResource(className); + iin = getClass().getClassLoader().getResourceAsStream(resourceName); + } + else { + iin = new FileInputStream(classPath); + } + + DataInputStream in = new DataInputStream(iin); + + // magic number + in.read(buffer, 0, MAGIC.length); + assertArrayEquals(MAGIC); + + // version + in.read(buffer, 0, VERSION.length); + assertArrayEquals(VERSION); + + // constant_pool_count + int constant_pool_count = in.readUnsignedShort(); + System.out.println("Constant pool count: " + constant_pool_count); + + // indexed from 1 (0 will be unused) to constant_pool_count-1 + constant_pool = new Object[constant_pool_count]; + + // constant pool + for (int i = 1; i < constant_pool_count; i++) { + System.out.print(i + ": "); + int type = in.readUnsignedByte(); + switch(type) { + case CONSTANT_Utf8: + constant_pool[i] = new CONSTANT_Utf8_info(in); + break; + case CONSTANT_Class: + constant_pool[i] = new CONSTANT_Class_info(in); + break; + case CONSTANT_Methodref: + constant_pool[i] = new CONSTANT_Methodref_info(in); + break; + case CONSTANT_NameAndType: + constant_pool[i] = new CONSTANT_NameAndType_info(in); + break; + default: + fail("Unknown type: " + type); + } + System.out.println(constant_pool[i]); + } + + // access flags + int access_flags = in.readUnsignedShort(); + System.out.println("Access flags: " + access_flags); // see http://stackoverflow.com/questions/8949933/what-is-the-purpose-of-the-acc-super-access-flag-on-java-class-files + + // this class name + int this_class = in.readUnsignedShort(); + System.out.println("This class index: " + this_class); + + // super class name + int super_class = in.readUnsignedShort(); + System.out.println("This superclass index: " + super_class); + + // interfaces implemented count (we have none) + int interfaces_count = in.readUnsignedShort(); + System.out.println("Interfaces count: " + interfaces_count); + for (int i = 0; i < interfaces_count; i++) { + int index = in.readUnsignedShort(); + System.out.println("Interface " + i + " index: " + index); + } + + // fields count (we have none) + int fields_count = in.readUnsignedShort(); + System.out.println("Fields count: " + fields_count); + assertEquals("Reading fields isn't yet supported", 0, fields_count); + + //methods count (we have one) + int methods_count = in.readUnsignedShort(); + System.out.println("Methods count: " + methods_count); + + for (int i = 0; i < methods_count; i++) { + method_info methodInfo = new method_info(in); + System.out.println("for " + methodInfo); + } + + // reading final class attributes + int attributes_count = in.readUnsignedShort(); + System.out.println("Class attributes count: " + attributes_count); + for (int i = 0; i < attributes_count ; i++) { + attribute_info attributeInfo = new attribute_info(in); + } + + in.close(); + } + + private void assertArrayEquals(byte[] expected) { + for (int i = 0; i < expected.length; i++) { + if(expected[i] != buffer[i]) { + fail("Expected was " + Arrays.toString(expected) + " but actual is " + Arrays.toString(buffer)); + } + } + } +} diff --git a/main/src/test/java/org/objenesis/EmptyClass.java b/main/src/test/java/org/objenesis/EmptyClass.java new file mode 100644 index 0000000..a7f71ef --- /dev/null +++ b/main/src/test/java/org/objenesis/EmptyClass.java @@ -0,0 +1,30 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import java.util.Date; + +/** + * Just used for testing. To see the bytecode of a really simple class + * + * @author Henri Tremblay + */ +public class EmptyClass extends Date { + + public EmptyClass() { + throw new RuntimeException(); + } +} diff --git a/main/src/test/java/org/objenesis/ExternalizableTest.java b/main/src/test/java/org/objenesis/ExternalizableTest.java new file mode 100644 index 0000000..765bc45 --- /dev/null +++ b/main/src/test/java/org/objenesis/ExternalizableTest.java @@ -0,0 +1,49 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.junit.Test; + +import java.io.*; +import java.util.ArrayList; + +/** + * This test makes sure an issue mentioned is not occurring. + * @author Henri Tremblay + */ +public class ExternalizableTest { + + public static class A extends ArrayList<String> implements Externalizable { + + public A() { + } + + public void writeExternal(ObjectOutput out) throws IOException { + + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + + } + } + + @Test + public void test() { + A a = ObjenesisHelper.newSerializableInstance(A.class); + // This call should work because the ArrayList constructor as been called. This is required by A implementing Externalizable + a.add("Test"); + } +} diff --git a/main/src/test/java/org/objenesis/ObjenesisExceptionTest.java b/main/src/test/java/org/objenesis/ObjenesisExceptionTest.java index 407a2fd..a49dea5 100644 --- a/main/src/test/java/org/objenesis/ObjenesisExceptionTest.java +++ b/main/src/test/java/org/objenesis/ObjenesisExceptionTest.java @@ -1,54 +1,59 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import junit.framework.TestCase;
-
-/**
- * @author Henri Tremblay
- */
-public class ObjenesisExceptionTest extends TestCase {
-
- public final void testObjenesisExceptionString() {
- Exception e = new ObjenesisException("test");
- assertEquals("test", e.getMessage());
- }
-
- public final void testObjenesisExceptionThrowable() {
- Exception cause = new RuntimeException("test");
- Exception e = new ObjenesisException(cause);
- assertSame(cause, e.getCause());
- assertEquals(cause.toString(), e.getMessage());
-
- // Check null case
- e = new ObjenesisException((Throwable) null);
- assertNull(e.getCause());
- assertEquals(null, e.getMessage());
- }
-
- public final void testObjenesisExceptionStringThrowable() {
- Exception cause = new RuntimeException("test");
- Exception e = new ObjenesisException("msg", cause);
- assertSame(cause, e.getCause());
- assertEquals("msg", e.getMessage());
-
- // Check null case
- e = new ObjenesisException("test", null);
- assertNull(e.getCause());
- assertEquals("test", e.getMessage());
- }
-
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * @author Henri Tremblay + */ +public class ObjenesisExceptionTest { + + @Test + public final void testObjenesisExceptionString() { + Exception e = new ObjenesisException("test"); + assertEquals("test", e.getMessage()); + } + + @Test + public final void testObjenesisExceptionThrowable() { + Exception cause = new RuntimeException("test"); + Exception e = new ObjenesisException(cause); + assertSame(cause, e.getCause()); + assertEquals(cause.toString(), e.getMessage()); + + // Check null case + e = new ObjenesisException((Throwable) null); + assertNull(e.getCause()); + assertEquals(null, e.getMessage()); + } + + @Test + public final void testObjenesisExceptionStringThrowable() { + Exception cause = new RuntimeException("test"); + Exception e = new ObjenesisException("msg", cause); + assertSame(cause, e.getCause()); + assertEquals("msg", e.getMessage()); + + // Check null case + e = new ObjenesisException("test", null); + assertNull(e.getCause()); + assertEquals("test", e.getMessage()); + } + +} diff --git a/main/src/test/java/org/objenesis/ObjenesisTest.java b/main/src/test/java/org/objenesis/ObjenesisTest.java index eddd4a8..111e639 100644 --- a/main/src/test/java/org/objenesis/ObjenesisTest.java +++ b/main/src/test/java/org/objenesis/ObjenesisTest.java @@ -1,72 +1,90 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import junit.framework.TestCase;
-
-import org.objenesis.instantiator.ObjectInstantiator;
-import org.objenesis.strategy.InstantiatorStrategy;
-
-/**
- * @author Henri Tremblay
- */
-public class ObjenesisTest extends TestCase {
-
- public final void testObjenesis() {
- Objenesis o = new ObjenesisStd();
- assertEquals(
- "org.objenesis.ObjenesisStd using org.objenesis.strategy.StdInstantiatorStrategy with caching",
- o.toString());
- }
-
- public final void testObjenesis_WithoutCache() {
- Objenesis o = new ObjenesisStd(false);
- assertEquals(
- "org.objenesis.ObjenesisStd using org.objenesis.strategy.StdInstantiatorStrategy without caching",
- o.toString());
-
- assertEquals(o.getInstantiatorOf(getClass()).newInstance().getClass(), getClass());
- }
-
- public final void testNewInstance() {
- Objenesis o = new ObjenesisStd();
- assertEquals(getClass(), o.newInstance(getClass()).getClass());
- }
-
- public final void testGetInstantiatorOf() {
- Objenesis o = new ObjenesisStd();
- ObjectInstantiator i1 = o.getInstantiatorOf(getClass());
- // Test instance creation
- assertEquals(getClass(), i1.newInstance().getClass());
-
- // Test caching
- ObjectInstantiator i2 = o.getInstantiatorOf(getClass());
- assertSame(i1, i2);
- }
-
- public final void testToString() {
- Objenesis o = new ObjenesisStd() {};
- assertEquals(
- "org.objenesis.ObjenesisTest$1 using org.objenesis.strategy.StdInstantiatorStrategy with caching",
- o.toString());
- }
-}
-
-class MyStrategy implements InstantiatorStrategy {
- public ObjectInstantiator newInstantiatorOf(Class type) {
- return null;
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.strategy.InstantiatorStrategy; + +import static org.junit.Assert.*; + +/** + * @author Henri Tremblay + */ +public class ObjenesisTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public final void testObjenesis() { + Objenesis o = new ObjenesisStd(); + assertEquals( + "org.objenesis.ObjenesisStd using org.objenesis.strategy.StdInstantiatorStrategy with caching", + o.toString()); + } + + @Test + public final void testObjenesis_WithoutCache() { + Objenesis o = new ObjenesisStd(false); + assertEquals( + "org.objenesis.ObjenesisStd using org.objenesis.strategy.StdInstantiatorStrategy without caching", + o.toString()); + + assertEquals(o.getInstantiatorOf(getClass()).newInstance().getClass(), getClass()); + } + + @Test + public final void testNewInstance() { + Objenesis o = new ObjenesisStd(); + assertEquals(getClass(), o.newInstance(getClass()).getClass()); + } + + @Test + public final void testGetInstantiatorOf() { + Objenesis o = new ObjenesisStd(); + ObjectInstantiator<?> i1 = o.getInstantiatorOf(getClass()); + // Test instance creation + assertEquals(getClass(), i1.newInstance().getClass()); + + // Test caching + ObjectInstantiator<?> i2 = o.getInstantiatorOf(getClass()); + assertSame(i1, i2); + } + + @Test + public final void testGetInstantiatorOf_primitive() { + Objenesis o = new ObjenesisStd(); + expectedException.expect(IllegalArgumentException.class); + o.getInstantiatorOf(long.class); + } + + @Test + public final void testToString() { + Objenesis o = new ObjenesisStd() {}; + assertEquals( + "org.objenesis.ObjenesisTest$1 using org.objenesis.strategy.StdInstantiatorStrategy with caching", + o.toString()); + } +} + +class MyStrategy implements InstantiatorStrategy { + public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { + return null; + } +} diff --git a/main/src/test/java/org/objenesis/SerializingInstantiatorTest.java b/main/src/test/java/org/objenesis/SerializingInstantiatorTest.java index 7eb5081..528cb6d 100644 --- a/main/src/test/java/org/objenesis/SerializingInstantiatorTest.java +++ b/main/src/test/java/org/objenesis/SerializingInstantiatorTest.java @@ -1,45 +1,40 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis;
-
-import java.io.NotSerializableException;
-
-import junit.framework.TestCase;
-
-/**
- * @author Henri Tremblay
- * @author Leonardo Mesquita
- */
-public class SerializingInstantiatorTest extends TestCase {
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testNotSerializable() {
- ObjenesisSerializer o = new ObjenesisSerializer();
- try {
- o.newInstance(Object.class);
- fail("Should have thrown an exception");
- } catch (ObjenesisException e) {
- assertTrue(e.getCause() instanceof NotSerializableException);
- }
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis; + +import static org.junit.Assert.*; + +import java.io.NotSerializableException; + +import org.junit.Test; + +/** + * @author Henri Tremblay + * @author Leonardo Mesquita + */ +public class SerializingInstantiatorTest { + + @Test + public void testNotSerializable() { + ObjenesisSerializer o = new ObjenesisSerializer(); + try { + o.newInstance(Object.class); + fail("Should have thrown an exception"); + } catch (ObjenesisException e) { + assertTrue(e.getCause() instanceof NotSerializableException); + } + } +} diff --git a/main/src/test/java/org/objenesis/instantiator/basic/ClassDefinitionUtilsTest.java b/main/src/test/java/org/objenesis/instantiator/basic/ClassDefinitionUtilsTest.java new file mode 100644 index 0000000..50e01ca --- /dev/null +++ b/main/src/test/java/org/objenesis/instantiator/basic/ClassDefinitionUtilsTest.java @@ -0,0 +1,60 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author Henri Tremblay + */ +public class ClassDefinitionUtilsTest { + + String className = "org.objenesis.EmptyClass"; + + @Test + public void testDefineClass() throws Exception { + byte[] b = ClassDefinitionUtils.readClass(className); + Class<?> c = ClassDefinitionUtils.defineClass(className, b, getClass().getClassLoader()); + assertEquals(c.getName(), className); + } + + @Test + public void testClassNameToInternalClassName() { + String actual = ClassDefinitionUtils.classNameToInternalClassName(className); + assertEquals("org/objenesis/EmptyClass", actual); + } + + @Test + public void testClassNameToResource() { + String actual = ClassDefinitionUtils.classNameToResource(className); + assertEquals("org/objenesis/EmptyClass.class", actual); + } + + @Test + public void testGetExistingClass_existing() { + Class<?> actual = ClassDefinitionUtils.getExistingClass(getClass().getClassLoader(), + getClass().getName()); + assertSame(actual, getClass()); + } + + @Test + public void testGetExistingClass_notExisting() { + Class<?> actual = ClassDefinitionUtils.getExistingClass(getClass().getClassLoader(), getClass().getName() + "$$$1"); + assertNull(actual); + } +} diff --git a/main/src/test/java/org/objenesis/instantiator/basic/ProxyingInstantiatorTest.java b/main/src/test/java/org/objenesis/instantiator/basic/ProxyingInstantiatorTest.java new file mode 100644 index 0000000..7ccdffc --- /dev/null +++ b/main/src/test/java/org/objenesis/instantiator/basic/ProxyingInstantiatorTest.java @@ -0,0 +1,38 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.basic; + +import org.junit.Ignore; +import org.junit.Test; +import org.objenesis.EmptyClass; +import org.objenesis.instantiator.ObjectInstantiator; + +import static org.junit.Assert.*; + +/** + * @author Henri Tremblay + */ +@Ignore("Because it doesn't work without -Xverify:none") +public class ProxyingInstantiatorTest { + + @Test + public void testNewInstance() throws Exception { + ObjectInstantiator<EmptyClass> inst = new ProxyingInstantiator<EmptyClass>(EmptyClass.class); + EmptyClass c = inst.newInstance(); + assertEquals("EmptyClass$$$Objenesis", c.getClass().getSimpleName()); + } + +} diff --git a/main/src/test/java/org/objenesis/instantiator/sun/MagicInstantiatorTest.java b/main/src/test/java/org/objenesis/instantiator/sun/MagicInstantiatorTest.java new file mode 100644 index 0000000..ce11ced --- /dev/null +++ b/main/src/test/java/org/objenesis/instantiator/sun/MagicInstantiatorTest.java @@ -0,0 +1,54 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.instantiator.sun; + +import org.junit.Before; +import org.junit.Test; +import org.objenesis.EmptyClass; +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.strategy.PlatformDescription; + +import static org.junit.Assert.*; +import static org.junit.Assume.*; + +/** + * @author Henri Tremblay + */ +public class MagicInstantiatorTest { + + @Before + public void before() { + // I know it works one these two. Not sure on others + assumeTrue( + PlatformDescription.isThisJVM(PlatformDescription.HOTSPOT) || + PlatformDescription.isThisJVM(PlatformDescription.OPENJDK)); + } + + @Test + public void testNewInstance() throws Exception { + ObjectInstantiator<EmptyClass> o1 = new MagicInstantiator<EmptyClass>(EmptyClass.class); + assertEquals(EmptyClass.class, o1.newInstance().getClass()); + + ObjectInstantiator<EmptyClass> o2 = new MagicInstantiator<EmptyClass>(EmptyClass.class); + assertEquals(EmptyClass.class, o2.newInstance().getClass()); + } + + @Test + public void testInternalInstantiator() { + ObjectInstantiator<EmptyClass> o1 = new MagicInstantiator<EmptyClass>(EmptyClass.class).getInstantiator(); + assertEquals(EmptyClass.class, o1.newInstance().getClass()); + } +} diff --git a/main/src/test/java/org/objenesis/strategy/PlatformDescriptionTest.java b/main/src/test/java/org/objenesis/strategy/PlatformDescriptionTest.java new file mode 100644 index 0000000..22caca6 --- /dev/null +++ b/main/src/test/java/org/objenesis/strategy/PlatformDescriptionTest.java @@ -0,0 +1,51 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.strategy; + +import org.junit.Test; + +import java.lang.reflect.Method; + +import static org.junit.Assert.*; + +/** + * Currently the test just check nothing is crashing. A more complex test should play with class + * loading an properties + * + * @author Henri Tremblay + */ +public class PlatformDescriptionTest { + + @Test + public void isJvmName() { + PlatformDescription.isThisJVM(PlatformDescription.HOTSPOT); + } + + @Test + public void test() { + if(!PlatformDescription.isThisJVM(PlatformDescription.DALVIK)) { + assertEquals(0, PlatformDescription.ANDROID_VERSION); + } + } + + @Test + public void testAndroidVersion() throws Exception { + Method m = PlatformDescription.class.getDeclaredMethod("getAndroidVersion0"); + m.setAccessible(true); + int actual = (Integer) m.invoke(null); + assertEquals(42, actual); + } +} diff --git a/tck-android/.settings/org.eclipse.jdt.core.prefs b/tck-android/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index abec6ca..0000000 --- a/tck-android/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/tck-android/AndroidManifest.xml b/tck-android/AndroidManifest.xml index b17fbbc..61ef6af 100644 --- a/tck-android/AndroidManifest.xml +++ b/tck-android/AndroidManifest.xml @@ -1,21 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> - <!-- -Copyright 2006-2013 the original author or authors. -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 + Copyright 2006-2017 the original author or authors. - http://www.apache.org/licenses/LICENSE-2.0 + 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 -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. ---> + 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. +--> <!-- Describes an Android application with a single Instrumentation, which runs the Objenesis TCK. @@ -30,7 +30,7 @@ limitations under the License. <uses-sdk android:minSdkVersion="1" - android:targetSdkVersion="17" /> + android:targetSdkVersion="25" /> <application android:allowBackup="false"> <uses-library android:name="android.test.runner" /> @@ -38,6 +38,9 @@ limitations under the License. <instrumentation android:name=".TckInstrumentation" - android:targetPackage="org.objenesis.tck.android"> - </instrumentation> -</manifest>
\ No newline at end of file + android:targetPackage="org.objenesis.tck.android" /> + + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="org.objenesis.tck.android" + android:label="Objenesis Android TCK."/> +</manifest> diff --git a/tck-android/pom.xml b/tck-android/pom.xml index abb64a1..46369e7 100644 --- a/tck-android/pom.xml +++ b/tck-android/pom.xml @@ -1,103 +1,146 @@ -<?xml version="1.0" encoding="ISO-8859-1"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.objenesis</groupId>
- <artifactId>objenesis-parent</artifactId>
- <version>2.0-SNAPSHOT</version>
- </parent>
- <artifactId>objenesis-tck-android</artifactId>
- <name>Objenesis Android TCK</name>
- <description>Objenesis' TCK built for Android devices</description>
- <packaging>apk</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.objenesis</groupId>
- <artifactId>objenesis-tck</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.google.android</groupId>
- <artifactId>android</artifactId>
- <version>1.5_r3</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- <build>
- <sourceDirectory>src</sourceDirectory>
-
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>com.jayway.maven.plugins.android.generation2</groupId>
- <artifactId>android-maven-plugin</artifactId>
- <version>3.5.0</version>
- <extensions>true</extensions>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>com.jayway.maven.plugins.android.generation2</groupId>
- <artifactId>android-maven-plugin</artifactId>
- <configuration>
- <sdk>
- <platform>17</platform>
- </sdk>
- </configuration>
- <extensions>true</extensions>
- </plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <inherited>false</inherited>
- <executions>
- <execution>
- <id>install</id>
- <phase>integration-test</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>adb</executable>
- <arguments>
- <argument>install</argument>
- <argument>-r</argument>
- <argument>${project.build.directory}\${project.build.finalName}.apk</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>execute</id>
- <phase>integration-test</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <executable>adb</executable>
- <arguments>
- <argument>shell</argument>
- <argument>am</argument>
- <argument>instrument</argument>
- <argument>-w</argument>
- <argument>org.objenesis.tck.android/.TckInstrumentation</argument>
- </arguments>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+<?xml version="1.0" encoding="ISO-8859-1"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.objenesis</groupId> + <artifactId>objenesis-parent</artifactId> + <version>2.5</version> + </parent> + <artifactId>objenesis-tck-android</artifactId> + <name>Objenesis Android TCK</name> + <description>Objenesis' TCK built for Android devices</description> + <packaging>apk</packaging> + + <properties> + <android.home>${env.ANDROID_HOME}</android.home> + </properties> + + <dependencies> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>objenesis-tck</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.google.android</groupId> + <artifactId>android</artifactId> + <version>4.1.1.4</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.android</groupId> + <artifactId>android-test</artifactId> + <version>4.1.1.4</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <exclusions> + <exclusion> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>com.simpligility.maven.plugins</groupId> + <artifactId>android-maven-plugin</artifactId> + <version>4.4.3</version> + <extensions>true</extensions> + <configuration> + <testFailSafe>false</testFailSafe> + <test> + <instrumentationPackage>org.objenesis.tck.android</instrumentationPackage> + <instrumentationRunner>android.test.InstrumentationTestRunner</instrumentationRunner> + </test> + </configuration> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + + <plugin> + <groupId>com.keyboardsamurais.maven</groupId> + <artifactId>maven-timestamp-plugin</artifactId> + </plugin> + <plugin> + <groupId>com.mycila.maven-license-plugin</groupId> + <artifactId>maven-license-plugin</artifactId> + </plugin> + <plugin> + <artifactId>maven-remote-resources-plugin</artifactId> + </plugin> + + <plugin> + <groupId>com.simpligility.maven.plugins</groupId> + <artifactId>android-maven-plugin</artifactId> + <configuration> + <sdk> + <platform>25</platform> + </sdk> + </configuration> + <extensions>true</extensions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <inherited>false</inherited> + <executions> + <execution> + <id>execute</id> + <phase>integration-test</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <executable>${android.home}/platform-tools/adb</executable> + <arguments> + <argument>shell</argument> + <argument>am</argument> + <argument>instrument</argument> + <argument>-w</argument> + <argument>org.objenesis.tck.android/.TckInstrumentation</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + + </build> + + <profiles> + <profile> + <!-- To activate in IntelliJ. This will allow compilation because it seems IntelliJ can't retrieve + the objenesis classes shaded in the objenesis-tck jar --> + <id>intellij-specific</id> + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>objenesis</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </profile> + </profiles> +</project> diff --git a/tck-android/src/main/java/org/objenesis/tck/android/ObjenesisTest.java b/tck-android/src/main/java/org/objenesis/tck/android/ObjenesisTest.java new file mode 100644 index 0000000..76d6d0d --- /dev/null +++ b/tck-android/src/main/java/org/objenesis/tck/android/ObjenesisTest.java @@ -0,0 +1,92 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.android; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Map; + +import org.objenesis.ObjenesisSerializer; +import org.objenesis.ObjenesisStd; +import org.objenesis.tck.Main; +import org.objenesis.tck.Reporter; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * Test case running the entire tck on android. + * + * @author Henri Tremblay + */ +public class ObjenesisTest extends AndroidTestCase { + + public static class JUnitReporter implements Reporter { + + private String currentObjenesis; + + private String currentCandidate; + + public void startTests(String platformDescription, Map<String, Object> allCandidates, + Map<String, Object> allInstantiators) { + } + + public void startTest(String candidateDescription, String objenesisDescription) { + currentCandidate = candidateDescription; + currentObjenesis = objenesisDescription; + } + + public void endObjenesis(String description) { + } + + public void endTests() { + } + + public void exception(Exception exception) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(buffer); + out.println("Exception when instantiating " + currentCandidate + " with " + + currentObjenesis + ": "); + exception.printStackTrace(out); + fail(buffer.toString()); + } + + public void result(boolean instantiatedObject) { + assertTrue("Instantiating " + currentCandidate + " with " + currentObjenesis + " failed", + instantiatedObject); + } + + public void endTest() { + } + } + + @SmallTest + public void testObjenesisStd() throws Exception { + Main.runStandardTest(new ObjenesisStd(), new JUnitReporter()); + } + + @SmallTest + public void testObjenesisSerializer() throws Exception { + Main.runSerializerTest(new ObjenesisSerializer(), new JUnitReporter()); + } + + @SmallTest + public void testObjenesisSerializerParentConstructorCalled() throws Exception { + boolean result = Main.runParentConstructorTest(new ObjenesisSerializer()); + assertTrue(result); + } + +}
\ No newline at end of file diff --git a/tck-android/src/main/java/org/objenesis/tck/android/TckInstrumentation.java b/tck-android/src/main/java/org/objenesis/tck/android/TckInstrumentation.java index 23ee5cf..575b671 100644 --- a/tck-android/src/main/java/org/objenesis/tck/android/TckInstrumentation.java +++ b/tck-android/src/main/java/org/objenesis/tck/android/TckInstrumentation.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.objenesis.tck.android; import android.app.Activity; import android.app.Instrumentation; import android.os.Bundle; - import org.objenesis.tck.Main; +import org.objenesis.tck.TextReporter; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -33,21 +32,31 @@ import java.io.PrintStream; */ public class TckInstrumentation extends Instrumentation { + @Override public void onCreate(Bundle arguments) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outputStream); System.setOut(printStream); + System.setErr(printStream); try { - Main.main(new String[0]); + launch(); } catch (IOException e) { e.printStackTrace(); } - + Bundle bundle = new Bundle(); String fromStdout = outputStream.toString(); bundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, fromStdout); finish(Activity.RESULT_OK, bundle); } -} + private void launch() throws IOException { + TextReporter reporter = new TextReporter(System.out, System.err); + + boolean parentConstructorTestSuccessful = Main.run(reporter); + + reporter.printResult(parentConstructorTestSuccessful); + + } +} diff --git a/tck/.settings/org.eclipse.jdt.core.prefs b/tck/.settings/org.eclipse.jdt.core.prefs index 302c5cb..0185411 100644 --- a/tck/.settings/org.eclipse.jdt.core.prefs +++ b/tck/.settings/org.eclipse.jdt.core.prefs @@ -1,296 +1,296 @@ -eclipse.preferences.version=1
-org.eclipse.jdt.core.codeComplete.argumentPrefixes=
-org.eclipse.jdt.core.codeComplete.argumentSuffixes=
-org.eclipse.jdt.core.codeComplete.fieldPrefixes=
-org.eclipse.jdt.core.codeComplete.fieldSuffixes=
-org.eclipse.jdt.core.codeComplete.localPrefixes=
-org.eclipse.jdt.core.codeComplete.localSuffixes=
-org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
-org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.3
-org.eclipse.jdt.core.compiler.compliance=1.3
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.3
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_assignment=0
-org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
-org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
-org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
-org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
-org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
-org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
-org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_after_package=1
-org.eclipse.jdt.core.formatter.blank_lines_before_field=0
-org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
-org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
-org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
-org.eclipse.jdt.core.formatter.blank_lines_before_method=1
-org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
-org.eclipse.jdt.core.formatter.blank_lines_before_package=0
-org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
-org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
-org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
-org.eclipse.jdt.core.formatter.comment.format_block_comments=true
-org.eclipse.jdt.core.formatter.comment.format_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=false
-org.eclipse.jdt.core.formatter.comment.format_html=true
-org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
-org.eclipse.jdt.core.formatter.comment.format_line_comments=true
-org.eclipse.jdt.core.formatter.comment.format_source_code=true
-org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
-org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
-org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
-org.eclipse.jdt.core.formatter.comment.line_length=100
-org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
-org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
-org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
-org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=1
-org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
-org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
-org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
-org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
-org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
-org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_empty_lines=false
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
-org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
-org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=3
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
-org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
-org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
-org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
-org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
-org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
-org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
-org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
-org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
-org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
-org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
-org.eclipse.jdt.core.formatter.join_lines_in_comments=true
-org.eclipse.jdt.core.formatter.join_wrapped_lines=true
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=100
-org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
-org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
-org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
-org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=3
-org.eclipse.jdt.core.formatter.use_on_off_tags=false
-org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
-org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
-org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
-org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+eclipse.preferences.version=1 +org.eclipse.jdt.core.codeComplete.argumentPrefixes= +org.eclipse.jdt.core.codeComplete.argumentSuffixes= +org.eclipse.jdt.core.codeComplete.fieldPrefixes= +org.eclipse.jdt.core.codeComplete.fieldSuffixes= +org.eclipse.jdt.core.codeComplete.localPrefixes= +org.eclipse.jdt.core.codeComplete.localSuffixes= +org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert +org.eclipse.jdt.core.formatter.comment.line_length=100 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=1 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=3 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=100 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=3 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/tck/.settings/org.eclipse.jdt.ui.prefs b/tck/.settings/org.eclipse.jdt.ui.prefs index 7aaa343..0a73ed8 100644 --- a/tck/.settings/org.eclipse.jdt.ui.prefs +++ b/tck/.settings/org.eclipse.jdt.ui.prefs @@ -1,9 +1,62 @@ -eclipse.preferences.version=1
-formatter_profile=_Objenesis
-formatter_settings_version=12
-org.eclipse.jdt.ui.exception.name=e
-org.eclipse.jdt.ui.gettersetter.use.is=true
-org.eclipse.jdt.ui.javadoc=false
-org.eclipse.jdt.ui.keywordthis=false
-org.eclipse.jdt.ui.overrideannotation=true
-org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_Objenesis +formatter_settings_version=12 +org.eclipse.jdt.ui.exception.name=e +org.eclipse.jdt.ui.gettersetter.use.is=true +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.keywordthis=false +org.eclipse.jdt.ui.overrideannotation=true +org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/> +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=true +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/tck/pom.xml b/tck/pom.xml index ba02bba..8a4992d 100644 --- a/tck/pom.xml +++ b/tck/pom.xml @@ -1,275 +1,168 @@ -<?xml version="1.0" encoding="ISO-8859-1"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.objenesis</groupId>
- <artifactId>objenesis-parent</artifactId>
- <version>2.0-SNAPSHOT</version>
- </parent>
- <artifactId>objenesis-tck</artifactId>
-
- <name>Objenesis TCK</name>
- <description>Objenesis' TCK</description>
- <url>http://objenesis.org</url>
-
- <properties>
- <!-- These versions are also used to filter boot-bundles.properties -->
- <log4j.version>1.2.17</log4j.version>
- <spring.osgi.version>1.2.1</spring.osgi.version>
- <slf4j.version>1.7.2</slf4j.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.objenesis</groupId>
- <artifactId>objenesis</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- Dependencies below are for the OSGi test -->
-
- <dependency>
- <groupId>org.springframework.osgi</groupId>
- <artifactId>spring-osgi-test</artifactId>
- <version>${spring.osgi.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.osgi</groupId>
- <artifactId>spring-osgi-annotation</artifactId>
- <version>${spring.osgi.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.osgi</groupId>
- <artifactId>spring-osgi-extender</artifactId>
- <version>${spring.osgi.version}</version>
- <scope>test</scope>
- </dependency>
-
- <!-- These are just to have a nice logging -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
- <scope>test</scope>
- </dependency>
-
- <!-- And this is our Equinox implementation -->
- <dependency>
- <groupId>org.eclipse</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <version>3.8.0.v20120529-1548</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <testResources>
- <testResource>
- <directory>test</directory>
- <filtering>true</filtering>
- </testResource>
- </testResources>
- <plugins>
- <plugin>
- <groupId>com.keyboardsamurais.maven</groupId>
- <artifactId>maven-timestamp-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>com.google.code.maven-license-plugin</groupId>
- <artifactId>maven-license-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-remote-resources-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.objenesis.tck.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>1.6</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <configuration>
- <links>
- <link>http://objenesis.googlecode.com/svn/docs/apidocs/</link>
- </links>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>jvm-test</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <executions>
- <execution>
- <id>Sun 1.3</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${sun_jdk1_3.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>Sun 1.4</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${sun_jdk1_4.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>Sun 1.5</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${sun_jdk1_5.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>Sun 1.6</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${sun_jdk1_6.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>Sun 1.7</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${sun_jdk1_7.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>JRockit for Java 1.3</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${jrockit1_3.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>JRockit for Java 1.4</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${jrockit1_4.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>JRockit for Java 1.5</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${jrockit1_5.jvm}</jvm>
- </configuration>
- </execution>
- <execution>
- <id>JRockit for Java 1.6</id>
- <goals>
- <goal>test</goal>
- </goals>
- <phase>test</phase>
- <configuration>
- <jvm>${jrockit1_6.jvm}</jvm>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <!-- Activate to create a complete release -->
- <id>release</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <inherited>false</inherited>
- <configuration>
- <executable>java</executable>
- <arguments>
- <argument>-jar</argument>
- <argument>${project.build.directory}\${project.build.finalName}.jar</argument>
- </arguments>
- </configuration>
- <executions>
- <execution>
- <id>test-release</id>
- <phase>integration-test</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
+<?xml version="1.0" encoding="ISO-8859-1"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.objenesis</groupId> + <artifactId>objenesis-parent</artifactId> + <version>2.5</version> + </parent> + <artifactId>objenesis-tck</artifactId> + + <name>Objenesis TCK</name> + <description>Objenesis' TCK</description> + <url>http://objenesis.org</url> + + <properties> + <paxexam.version>3.5.0</paxexam.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Dependencies below are for the OSGi test --> + + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-junit4</artifactId> + <version>${paxexam.version}</version> + <scope>test</scope> + <exclusions> + <!-- Use the one bundled in Felix --> + <exclusion> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-container-native</artifactId> + <version>${paxexam.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-link-mvn</artifactId> + <version>${paxexam.version}</version> + <scope>test</scope> + </dependency> + + <!-- And this is our OSGi container --> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.framework</artifactId> + <version>5.6.1</version> + <scope>test</scope> + </dependency> + + <!-- This is just to have a nice logging --> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>1.1.7</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>com.keyboardsamurais.maven</groupId> + <artifactId>maven-timestamp-plugin</artifactId> + </plugin> + <plugin> + <groupId>com.mycila.maven-license-plugin</groupId> + <artifactId>maven-license-plugin</artifactId> + </plugin> + <plugin> + <artifactId>maven-remote-resources-plugin</artifactId> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>org.objenesis.tck.Main</mainClass> + </manifest> + </archive> + </configuration> + </plugin> + <plugin> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <createDependencyReducedPom>false</createDependencyReducedPom> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>jvm-test</id> + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <executions> + <execution> + <id>specific-jvm</id> + <goals> + <goal>test</goal> + </goals> + <phase>test</phase> + <configuration> + <jvm>${my.jvm}</jvm> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + <profile> + <!-- Activate to perform integration tests --> + <id>full</id> + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <inherited>false</inherited> + <configuration> + <executable>java</executable> + <arguments> + <argument>-jar</argument> + <argument>${project.build.directory}/${project.build.finalName}.jar</argument> + </arguments> + </configuration> + <executions> + <execution> + <id>test-release</id> + <phase>integration-test</phase> + <goals> + <goal>exec</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/tck/src/main/java/org/objenesis/tck/CandidateLoader.java b/tck/src/main/java/org/objenesis/tck/CandidateLoader.java index 294fd50..12f38b9 100644 --- a/tck/src/main/java/org/objenesis/tck/CandidateLoader.java +++ b/tck/src/main/java/org/objenesis/tck/CandidateLoader.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,9 @@ import java.io.PrintStream; import java.util.Properties; /** - * Loads a set of candidate classes from a properties file into the TCK. <p/> The properties file - * takes the form of candidateClassName=shortDescription. + * Loads a set of candidate classes from a properties file into the TCK. + * <p> + * The properties file takes the form of candidateClassName=shortDescription. * * @author Joe Walnes * @see TCK @@ -36,7 +37,7 @@ public class CandidateLoader { /** * Handler for reporting errors from the CandidateLoader. */ - public static interface ErrorHandler { + public interface ErrorHandler { /** * Called whenever, trying to retrieve a candidate class from its name, a * ClassNotFoundException is thrown @@ -88,6 +89,7 @@ public class CandidateLoader { // entries directly to the TCK (which retains order). Properties properties = new Properties() { private static final long serialVersionUID = 1L; + @Override public Object put(Object key, Object value) { handlePropertyEntry((String) key, (String) value); return null; @@ -103,7 +105,7 @@ public class CandidateLoader { * @param resource File name * @throws IOException If there's problem reading the file */ - public void loadFromResource(Class cls, String resource) throws IOException { + public void loadFromResource(Class<?> cls, String resource) throws IOException { InputStream candidatesConfig = cls.getResourceAsStream(resource); if(candidatesConfig == null) { throw new IOException("Resource '" + resource + "' not found relative to " + cls.getName()); @@ -118,7 +120,7 @@ public class CandidateLoader { private void handlePropertyEntry(String key, String value) { try { - Class candidate = Class.forName(key, true, classloader); + Class<?> candidate = Class.forName(key, true, classloader); tck.registerCandidate(candidate, value); } catch(ClassNotFoundException e) { diff --git a/tck/src/main/java/org/objenesis/tck/Main.java b/tck/src/main/java/org/objenesis/tck/Main.java index 8634cfb..3c6b02b 100644 --- a/tck/src/main/java/org/objenesis/tck/Main.java +++ b/tck/src/main/java/org/objenesis/tck/Main.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,16 @@ */ package org.objenesis.tck; -import java.io.IOException; -import java.io.Serializable; - import org.objenesis.Objenesis; import org.objenesis.ObjenesisSerializer; import org.objenesis.ObjenesisStd; +import java.io.IOException; +import java.io.Serializable; + /** * Command line launcher for Technology Compatibility Kit (TCK). - * + * * @author Joe Walnes * @see TCK */ @@ -44,9 +44,10 @@ public class Main { private static class MockClass extends MockSuperClass implements Serializable { private static final long serialVersionUID = 1L; - + private final boolean constructorCalled; + @SuppressWarnings("unused") public MockClass() { constructorCalled = true; } @@ -58,7 +59,7 @@ public class Main { /** * Main class of the TCK. Can also be called as a normal method from an application server. - * + * * @param args No parameters are required * @throws IOException When the TCK fails to read properties' files. */ @@ -66,37 +67,93 @@ public class Main { TextReporter reporter = new TextReporter(System.out, System.err); - runTest(new ObjenesisStd(), reporter, "Objenesis std", "candidates/candidates.properties"); - runTest(new ObjenesisSerializer(), reporter, "Objenesis serializer", - "candidates/serializable-candidates.properties"); - - boolean result = runParentConstructorTest(); + boolean result = run(reporter); reporter.printResult(result); + + if(reporter.hasErrors()) { + System.exit(1); + } + } + + /** + * Run the full test suite using standard Objenesis instances + * + * @param reporter result are recorded in the reporter + * @return if the parent constructor test was successful + */ + public static boolean run(Reporter reporter) { + runStandardTest(new ObjenesisStd(), reporter); + runSerializerTest(new ObjenesisSerializer(), reporter); + + boolean result = runParentConstructorTest(new ObjenesisSerializer()); + return result; } - private static boolean runParentConstructorTest() { + /** + * Run the serializing suite on the provided Objenesis instance + * + * @param reporter result are recorded in the reporter + * @param objenesis Objenesis instance to test + */ + public static void runSerializerTest(Objenesis objenesis, Reporter reporter) { + runTest(objenesis, reporter, "Objenesis serializer", + "candidates/serializable-candidates.properties"); + } + + /** + * Run the standard suite on the provided Objenesis instance + * + * @param reporter result are recorded in the reporter + * @param objenesis Objenesis instance to test + */ + public static void runStandardTest(Objenesis objenesis, Reporter reporter) { + runTest(objenesis, reporter, "Objenesis std", "candidates/candidates.properties"); + } + + /** + * A special test making sure the first none serializable class no-args constructor is called + * + * @param objenesis Objenesis instance to test + * @return if the test was successful + */ + public static boolean runParentConstructorTest(Objenesis objenesis) { try { - Object result = new ObjenesisSerializer().newInstance(MockClass.class); + Object result = objenesis.newInstance(MockClass.class); MockClass mockObject = (MockClass) result; return mockObject.isSuperConstructorCalled() && !mockObject.isConstructorCalled(); } catch(Exception e) { - System.err.println("--- Not serializable parent constructor called ---"); + System.err.println("--- Not serializable parent constructor called as expected ---"); e.printStackTrace(System.err); return false; } } - private static void runTest(Objenesis objenesis, Reporter reporter, String description, - String candidates) throws IOException { + /** + * Run a suite of tests (candidates) on the Objenesis instance, sending the results to the + * reporter + * + * @param objenesis Objenesis instance to test + * @param reporter result are recorded in the reporter + * @param description description of the ran suite + * @param candidates property file containing a list of classes to test (key) and their + * description (value) + */ + public static void runTest(Objenesis objenesis, Reporter reporter, String description, + String candidates) { TCK tck = new TCK(); tck.registerObjenesisInstance(objenesis, description); CandidateLoader candidateLoader = new CandidateLoader(tck, Main.class.getClassLoader(), new CandidateLoader.LoggingErrorHandler(System.err)); - candidateLoader.loadFromResource(Main.class, candidates); + try { + candidateLoader.loadFromResource(Main.class, candidates); + } + catch(IOException e) { + throw new RuntimeException(e); + } tck.runTests(reporter); } diff --git a/tck/src/main/java/org/objenesis/tck/Reporter.java b/tck/src/main/java/org/objenesis/tck/Reporter.java index a73783d..7217da0 100644 --- a/tck/src/main/java/org/objenesis/tck/Reporter.java +++ b/tck/src/main/java/org/objenesis/tck/Reporter.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ package org.objenesis.tck; -import java.util.Collection; +import java.util.Map; /** * Reports results from the TCK back to the user. @@ -38,11 +38,12 @@ public interface Reporter { * * @param platformDescription Description the platform being run on (i.e. JVM version, vendor, * etc). - * @param allCandidates Descriptions (String) of all candidates being used in tests. - * @param allObjenesisInstances Descriptions of all Objenesis instances being used in tests. + * @param allCandidates Descriptions (String) of all candidates (Object) being used in tests. + * @param allObjenesisInstances Descriptions (String) of all Objenesis instances (Object) being + * used in tests. */ - void startTests(String platformDescription, Collection allCandidates, - Collection allObjenesisInstances); + void startTests(String platformDescription, Map<String, Object> allCandidates, + Map<String, Object> allObjenesisInstances); /** * Report that a test between a candidate and an objenesis instance if about to start. diff --git a/tck/src/main/java/org/objenesis/tck/TCK.java b/tck/src/main/java/org/objenesis/tck/TCK.java index 00046e2..4f93b25 100644 --- a/tck/src/main/java/org/objenesis/tck/TCK.java +++ b/tck/src/main/java/org/objenesis/tck/TCK.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,21 +15,21 @@ */ package org.objenesis.tck; +import org.objenesis.Objenesis; +import org.objenesis.strategy.PlatformDescription; + import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; -import org.objenesis.Objenesis; - /** * <b>Technology Compatibility Kit</b> (TCK) for {@link Objenesis}s. - * <p/> + * <p> * This TCK accepts a set of candidate classes (class it attempts to instantiate) and a set of * Objenesis implementations. It then tries instantiating every candidate with every Objenesis * implementations, reporting the results to a {@link Reporter}. + * * <h3>Example usage</h3> * * <pre> @@ -53,9 +53,9 @@ import org.objenesis.Objenesis; */ public class TCK { - private final List objenesisInstances = new ArrayList(); - private final List candidates = new ArrayList(); - private final Map descriptions = new HashMap(); + private final List<Objenesis> objenesisInstances = new ArrayList<Objenesis>(); + private final List<Class<?>> candidates = new ArrayList<Class<?>>(); + private final Map<Object, String> descriptions = new HashMap<Object, String>(); /** * Register a candidate class to attempt to instantiate. @@ -63,7 +63,7 @@ public class TCK { * @param candidateClass Class to attempt to instantiate * @param description Description of the class */ - public void registerCandidate(Class candidateClass, String description) { + public void registerCandidate(Class<?> candidateClass, String description) { candidates.add(candidateClass); descriptions.put(candidateClass, description); } @@ -86,20 +86,17 @@ public class TCK { */ public void runTests(Reporter reporter) { reporter.startTests(describePlatform(), findAllDescriptions(candidates, descriptions), - findAllDescriptions(objenesisInstances, descriptions)); + findAllDescriptions(objenesisInstances, descriptions)); - for(Iterator i = candidates.iterator(); i.hasNext();) { - Class candidateClass = (Class) i.next(); - String candidateDescription = (String) descriptions.get(candidateClass); + for(Class<?> candidateClass : candidates) { + String candidateDescription = descriptions.get(candidateClass); - for(Iterator j = objenesisInstances.iterator(); j.hasNext();) { - Objenesis objenesis = (Objenesis) j.next(); - - String objenesisDescription = (String) descriptions.get(objenesis); + for(Objenesis objenesis : objenesisInstances) { + String objenesisDescription = descriptions.get(objenesis); reporter.startTest(candidateDescription, objenesisDescription); - runTest(reporter, candidateClass, objenesis, candidateDescription); + runTest(reporter, candidateClass, objenesis); reporter.endTest(); } @@ -107,8 +104,7 @@ public class TCK { reporter.endTests(); } - private void runTest(Reporter reporter, Class candidate, Objenesis objenesis, - String candidateDescription) { + private void runTest(Reporter reporter, Class<?> candidate, Objenesis objenesis) { try { Object instance = objenesis.newInstance(candidate); boolean success = instance != null && instance.getClass() == candidate; @@ -119,10 +115,19 @@ public class TCK { } } - private Collection findAllDescriptions(List keys, Map descriptions) { - List results = new ArrayList(keys.size()); - for(int i = 0; i < keys.size(); i++) { - results.add(descriptions.get(keys.get(i))); + /** + * Return the human readable description for list of TCK items (Objenesis instances or test + * candidates) + * + * @param keys list of items for which we are searching for a description + * @param descriptions all descriptions + * @return map of items with their description. Will contain one entry per entry in the original + * key list + */ + private Map<String, Object> findAllDescriptions(List<?> keys, Map<?, String> descriptions) { + Map<String, Object> results = new HashMap<String, Object>(keys.size()); + for(Object o : keys) { + results.put(descriptions.get(o), o); } return results; } @@ -130,14 +135,11 @@ public class TCK { /** * Describes the platform. Outputs Java version and vendor. To change this behavior, override * this method. - * + * * @return Description of the current platform */ protected String describePlatform() { - return "Java " + System.getProperty("java.specification.version") + " (" - + System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name") + " " - + System.getProperty("java.vm.version") + " " + System.getProperty("java.runtime.version") - + ")"; + return PlatformDescription.describePlatform(); } } diff --git a/tck/src/main/java/org/objenesis/tck/TextReporter.java b/tck/src/main/java/org/objenesis/tck/TextReporter.java index f83c982..1c6b196 100644 --- a/tck/src/main/java/org/objenesis/tck/TextReporter.java +++ b/tck/src/main/java/org/objenesis/tck/TextReporter.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,21 +15,16 @@ */ package org.objenesis.tck; +import org.objenesis.Objenesis; + import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; +import java.util.*; /** * Reports results from TCK as tabulated text, suitable for dumping to the console or a file and - * being read by a human. If can be reused to provide a summary reports of different candidates as - * long as the same objenesisDescription is not used twice. - * + * being read by a human. It can be reused to provide a summary reports of different candidates as + * long as the same <code>objenesisDescription</code> is not used twice. + * * @author Joe Walnes * @author Henri Tremblay * @see TCK @@ -72,15 +67,15 @@ public class TextReporter implements Reporter { private int errorCount = 0; - private SortedSet allCandidates = new TreeSet(); + private SortedMap<String, Object> allCandidates = new TreeMap<String, Object>(); - private SortedSet allInstantiators = new TreeSet(); + private SortedMap<String, Object> allInstantiators = new TreeMap<String, Object>(); private String currentObjenesis; private String currentCandidate; - private Map objenesisResults = new HashMap(); + private Map<Object, Map<String, Result>> objenesisResults = new HashMap<Object, Map<String, Result>>(); private String platformDescription; @@ -93,18 +88,21 @@ public class TextReporter implements Reporter { this.log = log; } - public void startTests(String platformDescription, Collection allCandidates, - Collection allInstantiators) { + public int getErrorCount() { + return errorCount; + } + + public void startTests(String platformDescription, Map<String, Object> allCandidates, + Map<String, Object> allInstantiators) { // HT: in case the same reporter is reused, I'm guessing that it will - // always be the - // same platform + // always be the same platform this.platformDescription = platformDescription; - this.allCandidates.addAll(allCandidates); - this.allInstantiators.addAll(allInstantiators); + this.allCandidates.putAll(allCandidates); + this.allInstantiators.putAll(allInstantiators); - for(Iterator it = allInstantiators.iterator(); it.hasNext();) { - objenesisResults.put(it.next(), new HashMap()); + for(String desc : allInstantiators.keySet()) { + objenesisResults.put(desc, new HashMap<String, Result>()); } startTime = System.currentTimeMillis(); @@ -119,7 +117,8 @@ public class TextReporter implements Reporter { if(!instantiatedObject) { errorCount++; } - ((Map) objenesisResults.get(currentObjenesis)).put(currentCandidate, new Result( + objenesisResults.get(currentObjenesis).put(currentCandidate, + new Result( currentObjenesis, currentCandidate, instantiatedObject, null)); } @@ -127,7 +126,8 @@ public class TextReporter implements Reporter { errorCount++; - ((Map) objenesisResults.get(currentObjenesis)).put(currentCandidate, new Result( + objenesisResults.get(currentObjenesis).put(currentCandidate, + new Result( currentObjenesis, currentCandidate, false, exception)); } @@ -140,41 +140,53 @@ public class TextReporter implements Reporter { /** * Print the final summary report + * + * @param parentConstructorTest If the test checking that the none serializable constructor was called was successful */ public void printResult(boolean parentConstructorTest) { // Platform summary.println("Running TCK on platform: " + platformDescription); summary.println(); - summary.println("Not serializable parent constructor called: " + // Instantiator implementations + summary.println("Instantiators used: "); + for(Map.Entry<String, Object> o : allInstantiators.entrySet()) { + String inst = ((Objenesis) o.getValue()).getInstantiatorOf(String.class).getClass() + .getSimpleName(); + summary.println(" " + o.getKey() + ": " + inst); + } + summary.println(); + + // Parent constructor special test + summary.println("Not serializable parent constructor called as expected: " + (parentConstructorTest ? 'Y' : 'N')); summary.println(); - + if(!parentConstructorTest) { errorCount++; } - - int maxObjenesisWidth = lengthOfLongestStringIn(allInstantiators); - int maxCandidateWidth = lengthOfLongestStringIn(allCandidates); - // Header + Set<String> instantiators = this.allInstantiators.keySet(); + Set<String> candidates = this.allCandidates.keySet(); + + int maxObjenesisWidth = lengthOfLongestStringIn(instantiators); + int maxCandidateWidth = lengthOfLongestStringIn(candidates); + + // Strategy used summary.print(pad("", maxCandidateWidth) + ' '); - for(Iterator it = allInstantiators.iterator(); it.hasNext();) { - String desc = (String) it.next(); + for(String desc : instantiators) { summary.print(pad(desc, maxObjenesisWidth) + ' '); } summary.println(); - List exceptions = new ArrayList(); + List<Result> exceptions = new ArrayList<Result>(); // Candidates (and keep the exceptions meanwhile) - for(Iterator it = allCandidates.iterator(); it.hasNext();) { - String candidateDesc = (String) it.next(); + for(String candidateDesc : candidates) { summary.print(pad(candidateDesc, maxCandidateWidth) + ' '); - for(Iterator itInst = allInstantiators.iterator(); itInst.hasNext();) { - String instDesc = (String) itInst.next(); - Result result = (Result) ((Map) objenesisResults.get(instDesc)).get(candidateDesc); + for(String instDesc : instantiators) { + Result result = objenesisResults.get(instDesc).get(candidateDesc); if(result == null) { summary.print(pad("N/A", maxObjenesisWidth) + " "); } @@ -194,8 +206,7 @@ public class TextReporter implements Reporter { // Final if(errorCount != 0) { - for(Iterator it = exceptions.iterator(); it.hasNext();) { - Result element = (Result) it.next(); + for(Result element : exceptions) { log.println("--- Candidate '" + element.candidateDescription + "', Instantiator '" + element.objenesisDescription + "' ---"); element.exception.printStackTrace(log); @@ -213,6 +224,15 @@ public class TextReporter implements Reporter { summary.println(); } + /** + * Return true if the reporter has registered some errors + * + * @return if there was errors during execution + */ + public boolean hasErrors() { + return errorCount != 0; + } + private String pad(String text, int width) { if(text.length() == width) { return text; @@ -221,7 +241,7 @@ public class TextReporter implements Reporter { return text.substring(0, width); } else { - StringBuffer padded = new StringBuffer(text); + StringBuilder padded = new StringBuilder(text); while(padded.length() < width) { padded.append(' '); } @@ -229,10 +249,10 @@ public class TextReporter implements Reporter { } } - private int lengthOfLongestStringIn(Collection descriptions) { + private int lengthOfLongestStringIn(Collection<String> descriptions) { int result = 0; - for(Iterator it = descriptions.iterator(); it.hasNext();) { - result = Math.max(result, ((String) it.next()).length()); + for(Iterator<String> it = descriptions.iterator(); it.hasNext();) { + result = Math.max(result, it.next().length()); } return result; } diff --git a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorThrowingException.java b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorThrowingException.java index 43c3f7f..9f21909 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorThrowingException.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorThrowingException.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithArguments.java b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithArguments.java index caebcf3..5e60265 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithArguments.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithArguments.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithMandatoryArguments.java b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithMandatoryArguments.java index 52ae9c4..c8cab8e 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithMandatoryArguments.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/ConstructorWithMandatoryArguments.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPackageConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPackageConstructor.java index 7e05025..e66e6cf 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPackageConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPackageConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPrivateConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPrivateConstructor.java index d84a0eb..f0d5ebf 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPrivateConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPrivateConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/DefaultProtectedConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/DefaultProtectedConstructor.java index e3c665e..1254636 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/DefaultProtectedConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/DefaultProtectedConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPublicConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPublicConstructor.java index da595f1..6d5222c 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/DefaultPublicConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/DefaultPublicConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/NoConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/NoConstructor.java index df6ae4b..da1bc43 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/NoConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/NoConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorThrowingException.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorThrowingException.java index 4eb3f82..d5a7027 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorThrowingException.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorThrowingException.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithArguments.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithArguments.java index 88006dc..3113391 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithArguments.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithArguments.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithMandatoryArguments.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithMandatoryArguments.java index e495576..931bc97 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithMandatoryArguments.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableConstructorWithMandatoryArguments.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPackageConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPackageConstructor.java index 1147527..600fd81 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPackageConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPackageConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPrivateConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPrivateConstructor.java index 2a93746..a908468 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPrivateConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPrivateConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultProtectedConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultProtectedConstructor.java index bb2bc07..35545d5 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultProtectedConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultProtectedConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPublicConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPublicConstructor.java index 0e1c356..b7bb71b 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPublicConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableDefaultPublicConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableNoConstructor.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableNoConstructor.java index d9ee743..54157ff 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableNoConstructor.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableNoConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableReplacer.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableReplacer.java index ccfebbf..f887d21 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableReplacer.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableReplacer.java @@ -1,30 +1,30 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.tck.candidates;
-
-import java.io.Serializable;
-
-/**
- * @author Joe Walnes
- */
-public class SerializableReplacer implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- protected Object writeReplace() {
- return new SerializableResolver();
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.candidates; + +import java.io.Serializable; + +/** + * @author Joe Walnes + */ +public class SerializableReplacer implements Serializable { + + private static final long serialVersionUID = 1L; + + protected Object writeReplace() { + return new SerializableResolver(); + } +} diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableResolver.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableResolver.java index e5f01d4..7d6e766 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableResolver.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableResolver.java @@ -1,30 +1,30 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.tck.candidates;
-
-import java.io.Serializable;
-
-/**
- * @author Joe Walnes
- */
-public class SerializableResolver implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- protected Object readResolve() {
- return new SerializableReplacer();
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.candidates; + +import java.io.Serializable; + +/** + * @author Joe Walnes + */ +public class SerializableResolver implements Serializable { + + private static final long serialVersionUID = 1L; + + protected Object readResolve() { + return new SerializableReplacer(); + } +} diff --git a/tck/src/main/java/org/objenesis/tck/candidates/SerializableWithAncestorThrowingException.java b/tck/src/main/java/org/objenesis/tck/candidates/SerializableWithAncestorThrowingException.java index 9a73f78..980e12a 100644 --- a/tck/src/main/java/org/objenesis/tck/candidates/SerializableWithAncestorThrowingException.java +++ b/tck/src/main/java/org/objenesis/tck/candidates/SerializableWithAncestorThrowingException.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tck/src/main/java/org/objenesis/tck/search/ClassEnumerator.java b/tck/src/main/java/org/objenesis/tck/search/ClassEnumerator.java new file mode 100644 index 0000000..6de6d23 --- /dev/null +++ b/tck/src/main/java/org/objenesis/tck/search/ClassEnumerator.java @@ -0,0 +1,133 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.search; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * Taken and adapted from <a href="https://raw.githubusercontent.com/ddopson/java-class-enumerator/master/src/pro/ddopson/ClassEnumerator.java">here</a> + * + * @author Henri Tremblay + */ +public class ClassEnumerator { + + private static void processDirectory(File directory, String pkgname, SortedSet<String> classes) { + + // Get the list of the files contained in the package + String[] files = directory.list(); + + for (int i = 0; i < files.length; i++) { + String fileName = files[i]; + // we are only interested in .class files + if (fileName.endsWith(".class")) { + // removes the .class extension + String className = pkgname + '.' + fileName.substring(0, fileName.length() - 6); + classes.add(className); + continue; + } + + File subdir = new File(directory, fileName); + if (subdir.isDirectory()) { + processDirectory(subdir, pkgname + '.' + fileName, classes); + } + } + } + + private static void processJarfile(URL resource, String pkgname, SortedSet<String> classes) { + String relPath = pkgname.replace('.', '/'); + String resPath = resource.getPath(); + String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + JarFile jarFile; + try { + jarFile = new JarFile(jarPath); + } catch (IOException e) { + throw new RuntimeException("Unexpected IOException reading JAR File '" + jarPath + "'", e); + } + Enumeration<JarEntry> entries = jarFile.entries(); + while(entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + String className = null; + if(entryName.endsWith(".class") && entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { + className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + } + + if (className != null) { + classes.add(className); + } + } + } + + /** + * Return all the classes in this package recursively. The class loader of the {@code ClassEnumerator} class + * is used + * + * @param pkg the searched package + * @return list of full class names + */ + public static SortedSet<String> getClassesForPackage(Package pkg) { + return getClassesForPackage(pkg, ClassEnumerator.class.getClassLoader()); + } + + /** + * Return all the classes in this package recursively. + * + * @param pkg the searched package + * @return list of full class names + */ + public static SortedSet<String> getClassesForPackage(Package pkg, ClassLoader classLoader) { + SortedSet<String> classes = new TreeSet<String>(new Comparator<String>() { + public int compare(String o1, String o2) { + String simpleName1 = getSimpleName(o1); + String simpleName2 = getSimpleName(o2); + return simpleName1.compareTo(simpleName2); + } + + private String getSimpleName(String className) { + return className.substring(className.lastIndexOf('.')); + } + }); + + String pkgname = pkg.getName(); + String relPath = pkgname.replace('.', '/'); + + // Get a File object for the package + Enumeration<URL> resources; + try { + resources = classLoader.getResources(relPath); + } catch (IOException e) { + throw new RuntimeException(e); + } + + while(resources.hasMoreElements()) { + URL resource = resources.nextElement(); + if (resource.toString().startsWith("jar:")) { + processJarfile(resource, pkgname, classes); + } else { + processDirectory(new File(resource.getPath()), pkgname, classes); + } + } + + return classes; + } + +} diff --git a/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiator.java b/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiator.java new file mode 100644 index 0000000..5f11ff7 --- /dev/null +++ b/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiator.java @@ -0,0 +1,93 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.search; + +import org.objenesis.instantiator.ObjectInstantiator; +import org.objenesis.strategy.PlatformDescription; +import org.objenesis.tck.candidates.SerializableNoConstructor; + +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; +import java.util.SortedSet; + +/** + * This class will try every available instantiator on the platform to see which works. + * + * @author Henri Tremblay + */ +public class SearchWorkingInstantiator implements Serializable { // implements Serializable just for the test + + private SearchWorkingInstantiatorListener listener; + + public static void main(String[] args) throws Exception { + System.out.println(); + System.out.println(PlatformDescription.describePlatform()); + System.out.println(); + + SearchWorkingInstantiator searchWorkingInstantiator = new SearchWorkingInstantiator(new SystemOutListener()); + searchWorkingInstantiator.searchForInstantiator(SerializableNoConstructor.class); + } + + public SearchWorkingInstantiator(SearchWorkingInstantiatorListener listener) { + this.listener = listener; + } + + public void searchForInstantiator(Class<?> toInstantiate) { + SortedSet<String> classes = ClassEnumerator.getClassesForPackage(ObjectInstantiator.class.getPackage()); + + for (Iterator<String> it = classes.iterator(); it.hasNext();) { + String className = it.next(); + + // Skip if inner class of isn't named like a instantiator + if(className.contains("$") || !className.endsWith("Instantiator")) { + continue; + } + + Class<?> c = null; + try { + c = Class.forName(className); + } + catch(Exception e) { + listener.instantiatorUnsupported(c, e); + continue; + } + + if(c.isInterface() || !ObjectInstantiator.class.isAssignableFrom(c)) { + continue; + } + + Constructor<?> constructor; + try { + constructor = c.getConstructor(Class.class); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + + try { + ObjectInstantiator<?> instantiator = + (ObjectInstantiator<?>) constructor.newInstance(toInstantiate); + instantiator.newInstance(); + listener.instantiatorSupported(c); + } + catch(Exception e) { + Throwable t = (e instanceof InvocationTargetException) ? e.getCause() : e; + listener.instantiatorUnsupported(c, t); + } + } + } +} diff --git a/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiatorListener.java b/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiatorListener.java new file mode 100644 index 0000000..65214aa --- /dev/null +++ b/tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiatorListener.java @@ -0,0 +1,26 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.search; + +/** + * @author Henri Tremblay + */ +public interface SearchWorkingInstantiatorListener { + + void instantiatorSupported(Class<?> c); + + void instantiatorUnsupported(Class<?> c, Throwable t); +} diff --git a/tck/src/main/java/org/objenesis/tck/search/SystemOutListener.java b/tck/src/main/java/org/objenesis/tck/search/SystemOutListener.java new file mode 100644 index 0000000..dcae640 --- /dev/null +++ b/tck/src/main/java/org/objenesis/tck/search/SystemOutListener.java @@ -0,0 +1,40 @@ +/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck.search; + +import org.objenesis.instantiator.annotations.Instantiator; +import org.objenesis.instantiator.annotations.Typology; + +/** + * @author Henri Tremblay + */ +public class SystemOutListener implements SearchWorkingInstantiatorListener { + + private static final String PATTERN = "%-65s: %s%n"; + + public void instantiatorSupported(Class<?> c) { + System.out.printf(PATTERN, c.getSimpleName() + " (" + getTypology(c) + ")", "Working!"); + } + + public void instantiatorUnsupported(Class<?> c, Throwable t) { + System.out.printf(PATTERN, c.getSimpleName() + "(" + getTypology(c) + ")", "KO - " + t); + } + + private Typology getTypology(Class<?> c) { + Instantiator instantiatorAnn = c.getAnnotation(Instantiator.class); + return instantiatorAnn == null ? Typology.UNKNOWN : instantiatorAnn.value(); + } +} diff --git a/tck/src/main/resources/org/objenesis/tck/candidates/candidates.properties b/tck/src/main/resources/org/objenesis/tck/candidates/candidates.properties index 146c01d..41d74f8 100644 --- a/tck/src/main/resources/org/objenesis/tck/candidates/candidates.properties +++ b/tck/src/main/resources/org/objenesis/tck/candidates/candidates.properties @@ -1,41 +1,5 @@ # -# Copyright 2006-2013 the original author or authors. -# -# 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. -# -# 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. -# -# 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. +# Copyright 2006-2017 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -49,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + # List of candidate classes to attempt to instantiate in the Objenesis TCK. # Different visibilities of constructor. @@ -62,11 +27,11 @@ org.objenesis.tck.candidates.DefaultPackageConstructor org.objenesis.tck.candidates.SerializableDefaultPackageConstructor = Default package constructor (serializable) org.objenesis.tck.candidates.DefaultPrivateConstructor = Default private constructor org.objenesis.tck.candidates.SerializableDefaultPrivateConstructor = Default private constructor (serializable) -org.objenesis.tck.candidates.SerializableWithAncestorThrowingException = Serializable with ancestor throwing exception -org.objenesis.tck.candidates.SerializableReplacer = Serializable replacing with another class -org.objenesis.tck.candidates.SerializableResolver = Serializable resolving to another class +org.objenesis.tck.candidates.SerializableWithAncestorThrowingException = Serializable with ancestor throwing exception +org.objenesis.tck.candidates.SerializableReplacer = Serializable replacing with another class +org.objenesis.tck.candidates.SerializableResolver = Serializable resolving to another class -# Constructors that work with arguments passed in. +# Constructors that work with arguments passed in. org.objenesis.tck.candidates.ConstructorThrowingException = Constructor throwing exception org.objenesis.tck.candidates.SerializableConstructorThrowingException = Constructor throwing exception (serializable) org.objenesis.tck.candidates.ConstructorWithArguments = Constructor with arguments diff --git a/tck/src/main/resources/org/objenesis/tck/candidates/serializable-candidates.properties b/tck/src/main/resources/org/objenesis/tck/candidates/serializable-candidates.properties index 33c03ea..365f152 100644 --- a/tck/src/main/resources/org/objenesis/tck/candidates/serializable-candidates.properties +++ b/tck/src/main/resources/org/objenesis/tck/candidates/serializable-candidates.properties @@ -1,41 +1,5 @@ # -# Copyright 2006-2013 the original author or authors. -# -# 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. -# -# 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. -# -# 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. +# Copyright 2006-2017 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -49,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + # List of candidate classes to attempt to instantiate in the Objenesis TCK. # Different visibilities of constructor. @@ -57,10 +22,10 @@ org.objenesis.tck.candidates.SerializableDefaultPublicConstructor org.objenesis.tck.candidates.SerializableDefaultProtectedConstructor = Default protected constructor (serializable) org.objenesis.tck.candidates.SerializableDefaultPackageConstructor = Default package constructor (serializable) org.objenesis.tck.candidates.SerializableDefaultPrivateConstructor = Default private constructor (serializable) -org.objenesis.tck.candidates.SerializableReplacer = Serializable replacing with another class -org.objenesis.tck.candidates.SerializableResolver = Serializable resolving to another class +org.objenesis.tck.candidates.SerializableReplacer = Serializable replacing with another class +org.objenesis.tck.candidates.SerializableResolver = Serializable resolving to another class -# Constructors that work with arguments passed in. +# Constructors that work with arguments passed in. org.objenesis.tck.candidates.SerializableConstructorThrowingException = Constructor throwing exception (serializable) org.objenesis.tck.candidates.SerializableConstructorWithArguments = Constructor with arguments (serializable) org.objenesis.tck.candidates.SerializableConstructorWithMandatoryArguments = Constructor with mandatory arguments (serializable) diff --git a/tck/src/test/java/org/objenesis/tck/CandidateLoaderTest.java b/tck/src/test/java/org/objenesis/tck/CandidateLoaderTest.java index 7c0666b..94c3c4f 100644 --- a/tck/src/test/java/org/objenesis/tck/CandidateLoaderTest.java +++ b/tck/src/test/java/org/objenesis/tck/CandidateLoaderTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,25 +15,29 @@ */ package org.objenesis.tck; +import static org.junit.Assert.*; + import java.io.ByteArrayInputStream; import java.io.IOException; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; /** * @author Joe Walnes */ -public class CandidateLoaderTest extends TestCase { +public class CandidateLoaderTest { - private StringBuffer recordedEvents; + private StringBuilder recordedEvents; private CandidateLoader candidateLoader; - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { - recordedEvents = new StringBuffer(); + recordedEvents = new StringBuilder(); TCK tck = new TCK() { - public void registerCandidate(Class candidateClass, String description) { + @Override + public void registerCandidate(Class<?> candidateClass, String description) { recordedEvents.append("registerCandidate('").append(candidateClass).append("', '") .append(description).append("')\n"); } @@ -47,6 +51,7 @@ public class CandidateLoaderTest extends TestCase { candidateLoader = new CandidateLoader(tck, getClass().getClassLoader(), errorHandler); } + @Test public void testReadsClassesAndDescriptionsFromPropertiesFile() throws IOException { String input = "" + "org.objenesis.tck.CandidateLoaderTest$A = A candidate\n" + "\n" + "# a comment and some whitespace\n" + "\n" @@ -62,6 +67,7 @@ public class CandidateLoaderTest extends TestCase { recordedEvents.toString()); } + @Test public void testReportsMissingClassesToErrorHandler() throws IOException { String input = "" + "org.objenesis.tck.CandidateLoaderTest$A = A candidate\n" + "org.objenesis.tck.CandidateLoaderTest$NonExistant = Dodgy candidate\n" @@ -76,6 +82,7 @@ public class CandidateLoaderTest extends TestCase { recordedEvents.toString()); } + @Test public void testLoadsFromResourceInClassPath() throws IOException { // See CandidateLoaderTest-sample.properties. @@ -87,6 +94,7 @@ public class CandidateLoaderTest extends TestCase { recordedEvents.toString()); } + @Test public void testThrowsIOExceptionIfResourceNotInClassPath() throws IOException { try { candidateLoader.loadFromResource(getClass(), "Blatently-Bogus.properties"); diff --git a/tck/src/test/java/org/objenesis/tck/ObjenesisTest.java b/tck/src/test/java/org/objenesis/tck/ObjenesisTest.java index 95c3188..5b1073c 100644 --- a/tck/src/test/java/org/objenesis/tck/ObjenesisTest.java +++ b/tck/src/test/java/org/objenesis/tck/ObjenesisTest.java @@ -1,140 +1,90 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.tck;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.io.Serializable;
-import java.util.Collection;
-
-import junit.framework.TestCase;
-
-import org.objenesis.ObjenesisSerializer;
-import org.objenesis.ObjenesisStd;
-
-/**
- * Integration test for Objenesis. Should pass successfully on every supported JVM for all Objenesis
- * interface implementation.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisTest extends TestCase {
-
- public static class ErrorHandler implements CandidateLoader.ErrorHandler {
- public void classNotFound(String name) {
- fail("Class not found : " + name);
- }
- }
-
- public static class JUnitReporter implements Reporter {
-
- private String currentObjenesis;
-
- private String currentCandidate;
-
- public void startTests(String platformDescription, Collection allCandidates,
- Collection allInstantiators) {
- }
-
- public void startTest(String candidateDescription, String objenesisDescription) {
- currentCandidate = candidateDescription;
- currentObjenesis = objenesisDescription;
- }
-
- public void endObjenesis(String description) {
- }
-
- public void endTests() {
- }
-
- public void exception(Exception exception) {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- PrintStream out = new PrintStream(buffer);
- out.println("Exception when instantiating " + currentCandidate + " with "
- + currentObjenesis + ": ");
- exception.printStackTrace(out);
- fail(buffer.toString());
- }
-
- public void result(boolean instantiatedObject) {
- assertTrue("Instantiating " + currentCandidate + " with " + currentObjenesis + " failed",
- instantiatedObject);
- }
-
- public void endTest() {
- }
- }
-
- static class MockSuperClass {
- private final boolean superConstructorCalled;
- public MockSuperClass() {
- superConstructorCalled = true;
- }
- public boolean isSuperConstructorCalled() {
- return superConstructorCalled;
- }
- }
-
- static class MockClass extends MockSuperClass implements Serializable {
- private static final long serialVersionUID = 1L;
- private final boolean constructorCalled;
- public MockClass() {
- super();
- constructorCalled = true;
- }
- public boolean isConstructorCalled() {
- return constructorCalled;
- }
- }
-
- private TCK tck = null;
-
- private CandidateLoader candidateLoader = null;
-
- protected void setUp() throws Exception {
- super.setUp();
-
- tck = new TCK();
-
- candidateLoader = new CandidateLoader(tck, getClass().getClassLoader(), new ErrorHandler());
- }
-
- protected void tearDown() throws Exception {
- candidateLoader = null;
- tck = null;
- super.tearDown();
- }
-
- public void testObjenesisStd() throws Exception {
- candidateLoader.loadFromResource(getClass(), "candidates/candidates.properties");
- tck.registerObjenesisInstance(new ObjenesisStd(), "Objenesis standard");
- tck.runTests(new JUnitReporter());
- }
-
- public void testObjenesisSerializer() throws Exception {
- candidateLoader.loadFromResource(getClass(), "candidates/serializable-candidates.properties");
- tck.registerObjenesisInstance(new ObjenesisSerializer(), "Objenesis serializer");
- tck.runTests(new JUnitReporter());
- }
-
- public void testObjenesisSerializerParentConstructorCalled() throws Exception {
- Object result = new ObjenesisSerializer().newInstance(MockClass.class);
- assertEquals(MockClass.class, result.getClass());
- MockClass mockObject = (MockClass) result;
- assertTrue(mockObject.isSuperConstructorCalled());
- assertFalse(mockObject.isConstructorCalled());
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck; + +import static org.junit.Assert.*; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Map; + +import org.junit.Test; +import org.objenesis.ObjenesisSerializer; +import org.objenesis.ObjenesisStd; + +/** + * Integration test for Objenesis. Should pass successfully on every supported JVM for all Objenesis + * interface implementation. + * + * @author Henri Tremblay + */ +public class ObjenesisTest { + + public static class JUnitReporter implements Reporter { + + private String currentObjenesis; + + private String currentCandidate; + + public void startTests(String platformDescription, Map<String, Object> allCandidates, + Map<String, Object> allInstantiators) { + } + + public void startTest(String candidateDescription, String objenesisDescription) { + currentCandidate = candidateDescription; + currentObjenesis = objenesisDescription; + } + + public void endObjenesis(String description) { + } + + public void endTests() { + } + + public void exception(Exception exception) { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(buffer); + out.println("Exception when instantiating " + currentCandidate + " with " + + currentObjenesis + ": "); + exception.printStackTrace(out); + fail(buffer.toString()); + } + + public void result(boolean instantiatedObject) { + assertTrue("Instantiating " + currentCandidate + " with " + currentObjenesis + " failed", + instantiatedObject); + } + + public void endTest() { + } + } + + @Test + public void testObjenesisStd() throws Exception { + Main.runStandardTest(new ObjenesisStd(), new JUnitReporter()); + } + + @Test + public void testObjenesisSerializer() throws Exception { + Main.runSerializerTest(new ObjenesisSerializer(), new JUnitReporter()); + } + + @Test + public void testObjenesisSerializerParentConstructorCalled() throws Exception { + boolean result = Main.runParentConstructorTest(new ObjenesisSerializer()); + assertTrue(result); + } +} diff --git a/tck/src/test/java/org/objenesis/tck/OsgiTest.java b/tck/src/test/java/org/objenesis/tck/OsgiTest.java index 9679d71..d1e4b03 100644 --- a/tck/src/test/java/org/objenesis/tck/OsgiTest.java +++ b/tck/src/test/java/org/objenesis/tck/OsgiTest.java @@ -1,83 +1,100 @@ -/**
- * Copyright 2006-2013 the original author or authors.
- *
- * 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 org.objenesis.tck;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.objenesis.Objenesis;
-import org.objenesis.ObjenesisHelper;
-import org.springframework.osgi.test.AbstractConfigurableBundleCreatorTests;
-import org.w3c.dom.Document;
-
-/**
- * @author Henri Tremblay
- */
-public class OsgiTest extends AbstractConfigurableBundleCreatorTests implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- protected String[] getTestBundlesNames() {
- String version = getImplementationVersion(Objenesis.class);
- // Null means we are an IDE, not in Maven. So we have an IDE project dependency instead
- // of a Maven dependency with the jar. Which explains why the version is null (no Manifest
- // since there's no jar. In that case we get the version from the pom.xml and hope the Maven
- // jar is up-to-date in the local repository
- if(version == null) {
- try {
- XPathFactory xPathFactory = XPathFactory.newInstance();
- final XPath xPath = xPathFactory.newXPath();
- XPathExpression xPathExpression;
- try {
- xPathExpression = xPath.compile("/project/parent/version");
- }
- catch(final XPathExpressionException e) {
- throw new RuntimeException(e);
- }
-
- final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
- xmlFact.setNamespaceAware(false);
- final DocumentBuilder builder = xmlFact.newDocumentBuilder();
- final Document doc = builder.parse(new File("pom.xml"));
- version = xPathExpression.evaluate(doc);
- }
- catch(final Exception e) {
- throw new RuntimeException(e);
- }
- }
- return new String[] {"org.objenesis, objenesis, " + version};
- }
-
- public void testCanInstantiate() throws IOException {
- assertSame(OsgiTest.class, ObjenesisHelper.newInstance(getClass()).getClass());
- }
-
- public void testCanInstantiateSerialize() throws IOException {
- assertSame(OsgiTest.class, ObjenesisHelper.newSerializableInstance(getClass()).getClass());
- }
-
- protected String getImplementationVersion(final Class c) {
- return c.getPackage().getImplementationVersion();
- }
-}
+/** + * Copyright 2006-2017 the original author or authors. + * + * 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 org.objenesis.tck; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.objenesis.Objenesis; +import org.objenesis.ObjenesisHelper; +import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerMethod; +import org.w3c.dom.Document; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import static org.junit.Assert.*; +import static org.ops4j.pax.exam.CoreOptions.*; + +/** + * @author Henri Tremblay + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerMethod.class) +public class OsgiTest implements Serializable{ + + private static final long serialVersionUID = 1L; + + @Configuration + public Option[] config() { + String version = getImplementationVersion(Objenesis.class); + return options( + bundle("file:../main/target/objenesis-" + version + ".jar"), + junitBundles() + ); + } + + @Test + public void testCanInstantiate() throws IOException { + assertSame(OsgiTest.class, ObjenesisHelper.newInstance(getClass()).getClass()); + } + + @Test + public void testCanInstantiateSerialize() throws IOException { + assertSame(OsgiTest.class, ObjenesisHelper.newSerializableInstance(getClass()).getClass()); + } + + private String getImplementationVersion(final Class<?> c) { + String version = c.getPackage().getImplementationVersion(); + // Null means we are an IDE, not in Maven. So we have an IDE project dependency instead + // of a Maven dependency with the jar. Which explains why the version is null (no Manifest + // since there's no jar). In that case we get the version from the pom.xml. + if(version == null) { + try { + XPathFactory xPathFactory = XPathFactory.newInstance(); + final XPath xPath = xPathFactory.newXPath(); + XPathExpression xPathExpression; + try { + xPathExpression = xPath.compile("/project/parent/version"); + } + catch(final XPathExpressionException e) { + throw new RuntimeException(e); + } + + final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); + xmlFact.setNamespaceAware(false); + final DocumentBuilder builder = xmlFact.newDocumentBuilder(); + final Document doc = builder.parse(new File("pom.xml")); + version = xPathExpression.evaluate(doc); + } + catch(final Exception e) { + throw new RuntimeException(e); + } + } + return version; + } +} diff --git a/tck/src/test/java/org/objenesis/tck/TCKTest.java b/tck/src/test/java/org/objenesis/tck/TCKTest.java index 89718dd..0af4f04 100644 --- a/tck/src/test/java/org/objenesis/tck/TCKTest.java +++ b/tck/src/test/java/org/objenesis/tck/TCKTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,11 @@ */ package org.objenesis.tck; -import java.util.Collection; +import static org.junit.Assert.*; -import junit.framework.TestCase; +import java.util.Map; +import org.junit.Test; import org.objenesis.Objenesis; import org.objenesis.instantiator.ObjectInstantiator; @@ -26,28 +27,29 @@ import org.objenesis.instantiator.ObjectInstantiator; * @author Joe Walnes * @author Henri Tremblay */ -public class TCKTest extends TestCase { +public class TCKTest { public static class StubbedInstantiator1 implements Objenesis { - public Object newInstance(Class clazz) { + public <T> T newInstance(Class<T> clazz) { return null; } - public ObjectInstantiator getInstantiatorOf(Class clazz) { + public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { return null; } } public static class StubbedInstantiator2 implements Objenesis { - public Object newInstance(Class clazz) { + public <T> T newInstance(Class<T> clazz) { return null; } - public ObjectInstantiator getInstantiatorOf(Class clazz) { + public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { return null; } } + @Test public void testReportsAllCandidatesAndInstantiatorCombinationsToReporter() { // Given... a TCK with some candidate classes: A, B and C. TCK tck = new TCK(); @@ -75,6 +77,7 @@ public class TCKTest extends TestCase { + "result(false)\n" + "endTest()\n" + "endTests()\n", reporter.toString()); } + @Test public void testReportsSuccessIfCandidateCanBeInstantiated() { // Given... a TCK with some candidate classes: A, B and C. TCK tck = new TCK(); @@ -102,11 +105,11 @@ public class TCKTest extends TestCase { // Some sample classes used for testing. public static class SelectiveInstantiator implements Objenesis { - public Object newInstance(Class clazz) { - return clazz == CandidateA.class ? new CandidateA() : null; + public <T> T newInstance(Class<T> clazz) { + return clazz.cast(clazz == CandidateA.class ? new CandidateA() : null); } - public ObjectInstantiator getInstantiatorOf(Class clazz) { + public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { return null; } } @@ -128,10 +131,10 @@ public class TCKTest extends TestCase { */ private static class RecordingReporter implements Reporter { - private final StringBuffer log = new StringBuffer(); + private final StringBuilder log = new StringBuilder(); - public void startTests(String platformDescription, Collection allCandidates, - Collection allInstantiators) { + public void startTests(String platformDescription, Map<String, Object> allCandidates, + Map<String, Object> allInstantiators) { log.append("startTests()\n"); } @@ -156,6 +159,7 @@ public class TCKTest extends TestCase { log.append("endTests()\n"); } + @Override public String toString() { return log.toString(); } diff --git a/tck/src/test/java/org/objenesis/tck/TextReporterTest.java b/tck/src/test/java/org/objenesis/tck/TextReporterTest.java index f42093a..2a8b7c3 100644 --- a/tck/src/test/java/org/objenesis/tck/TextReporterTest.java +++ b/tck/src/test/java/org/objenesis/tck/TextReporterTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,32 +15,58 @@ */ package org.objenesis.tck; +import org.junit.Before; +import org.junit.Test; +import org.objenesis.Objenesis; +import org.objenesis.ObjenesisBase; +import org.objenesis.instantiator.basic.ConstructorInstantiator; +import org.objenesis.instantiator.basic.FailingInstantiator; +import org.objenesis.instantiator.basic.NullInstantiator; +import org.objenesis.strategy.SingleInstantiatorStrategy; + import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; -import junit.framework.TestCase; +import static org.junit.Assert.*; /** * @author Joe Walnes * @author Henri Tremblay */ -public class TextReporterTest extends TestCase { +public class TextReporterTest { private TextReporter textReporter; private ByteArrayOutputStream summaryBuffer; - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { summaryBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream logBuffer = new ByteArrayOutputStream(); textReporter = new TextReporter(new PrintStream(summaryBuffer), new PrintStream(logBuffer)); } + @Test public void testReportsSuccessesInTabularFormat() { - textReporter.startTests("Some platform", Arrays.asList(new String[] {"candidate A", - "candidate B", "candidate C"}), Arrays.asList(new String[] {"instantiator1", - "instantiator2", "instantiator3"})); + Map<String, Object> candidates = new HashMap<String, Object>(); + candidates.put("candidate A", "A"); + candidates.put("candidate B", "B"); + candidates.put("candidate C", "C"); + Map<String, Object> instantiators = new HashMap<String, Object>(); + + Objenesis instantiator1 = new ObjenesisBase(new SingleInstantiatorStrategy( + ConstructorInstantiator.class)); + Objenesis instantiator2 = new ObjenesisBase(new SingleInstantiatorStrategy( + FailingInstantiator.class)); + Objenesis instantiator3 = new ObjenesisBase(new SingleInstantiatorStrategy( + NullInstantiator.class)); + + instantiators.put("instantiator1", instantiator1); + instantiators.put("instantiator2", instantiator2); + instantiators.put("instantiator3", instantiator3); + + textReporter.startTests("Some platform", candidates, instantiators); textReporter.startTest("candidate A", "instantiator1"); textReporter.result(false); @@ -71,7 +97,12 @@ public class TextReporterTest extends TestCase { PrintStream out = new PrintStream(expectedSummaryBuffer); out.println("Running TCK on platform: Some platform"); out.println(); - out.println("Not serializable parent constructor called: Y"); + out.println("Instantiators used: "); + out.println(" instantiator1: ConstructorInstantiator"); + out.println(" instantiator2: FailingInstantiator"); + out.println(" instantiator3: NullInstantiator"); + out.println(); + out.println("Not serializable parent constructor called as expected: Y"); out.println(); out.println(" instantiator1 instantiator2 instantiator3 "); out.println("candidate A n n Y "); diff --git a/tck/src/test/java/org/springframework/osgi/test/internal/boot-bundles.properties b/tck/src/test/java/org/springframework/osgi/test/internal/boot-bundles.properties deleted file mode 100644 index 7d19172..0000000 --- a/tck/src/test/java/org/springframework/osgi/test/internal/boot-bundles.properties +++ /dev/null @@ -1,117 +0,0 @@ -# -# Copyright 2006-2013 the original author or authors. -# -# 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. -# -# 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. -# -# START OF EDITION -# This file is loaded by org.springframework.osgi.test.AbstractDependencyManagerTests. The -# original file is located in spring-osgi-test-1.2.1.jar. Changes to the original are tagged -# with "EDITED" -# END OF EDITION -# -# Properties file indicating the boot (or mandatory) bundles that are loaded -# by the testing framework. -# -# Normally, this file should not be edited since it is used by the testing infrastructure. -# Users that want to install bundles before starting a test, should use #bundles() method. -# - -# -# format: <groupId,artifactId,version>=+/-15 -# - the optional value is used to install/remove bundles if running on JDK >= 1.5 -# - see Spring org.springframework.core.JdkVersion for jdk major version codes. - -# elements that have to be ignored should star with -# ignore - -# Note: inner placeholders are not supported. - -# -# common properties -# - -# versioning -ignore.backport.version=3.1.0 -ignore.junit.version=3.8.2 -# EDITED: Upgrade the version from 1.2.15-SNAPSHOT to ${log4j.version} -ignore.log4j.version=${log4j.version} - -ignore.spring.version=2.5.6.SEC01 -# EDITED: Filter the version to match the pom -ignore.spring.osgi.version=${spring.osgi.version} -# EDITED: Upgraded from 1.5.0 -ignore.slf4j.version=${slf4j.version} -ignore.asm.version=2.2.3 - -# groupIds -ignore.spring.groupId=org.springframework -ignore.spring.osgi.groupId=org.springframework.osgi -ignore.slf4j.groupId=org.slf4j -# EDITED: Switch from org.springframework.osgi to log4j -ignore.log4j.groupId=log4j - -# -# actual libraries -# -# listed in dependency order to ease deployment - - -# dependencies - -# junit -org.junit,com.springsource.junit,${ignore.junit.version}= -# log4j -# EDITED: Change the groupId for log4j -${ignore.log4j.groupId},log4j,${ignore.log4j.version}= -# slf4j (commons-logging API) -#${ignore.slf4j.groupId},slf4j-api,${ignore.slf4j.version}= -#${ignore.slf4j.groupId},slf4j-log4j12,${ignore.slf4j.version}= -#${ignore.slf4j.groupId},jcl104-over-slf4j,${ignore.slf4j.version}= -# slf4j (BRITS) -# EDITED: Change the groupId for and artifactId -${ignore.slf4j.groupId},slf4j-api,${ignore.slf4j.version}= -${ignore.slf4j.groupId},slf4j-log4j12,${ignore.slf4j.version}= -${ignore.slf4j.groupId},jcl-over-slf4j,${ignore.slf4j.version}= -# aop alliance -org.aopalliance,com.springsource.org.aopalliance,1.0.0= -# asm -org.objectweb.asm,com.springsource.org.objectweb.asm,${ignore.asm.version}= -# backport concurrent -edu.emory.mathcs.backport,com.springsource.edu.emory.mathcs.backport,${ignore.backport.version}=-15 - -# spring libs -${ignore.spring.groupId},org.springframework.beans,${ignore.spring.version}= -${ignore.spring.groupId},org.springframework.core,${ignore.spring.version}= -${ignore.spring.groupId},org.springframework.context,${ignore.spring.version}= -${ignore.spring.groupId},org.springframework.aop,${ignore.spring.version}= -${ignore.spring.groupId},org.springframework.test,${ignore.spring.version}= - - -# spring osgi libs -${ignore.spring.osgi.groupId},spring-osgi-io,${ignore.spring.osgi.version}= -${ignore.spring.osgi.groupId},spring-osgi-core,${ignore.spring.osgi.version}= -${ignore.spring.osgi.groupId},spring-osgi-annotation,${ignore.spring.osgi.version}=+15 -${ignore.spring.osgi.groupId},spring-osgi-extender,${ignore.spring.osgi.version}= -${ignore.spring.osgi.groupId},spring-osgi-test,${ignore.spring.osgi.version}= diff --git a/tck/src/test/resources/logback-test.xml b/tck/src/test/resources/logback-test.xml new file mode 100644 index 0000000..96f5840 --- /dev/null +++ b/tck/src/test/resources/logback-test.xml @@ -0,0 +1,29 @@ +<!-- + + Copyright 2006-2017 the original author or authors. + + 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. + +--> +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> +</configuration> diff --git a/tck/src/test/resources/org/objenesis/tck/CandidateLoaderTest-sample.properties b/tck/src/test/resources/org/objenesis/tck/CandidateLoaderTest-sample.properties index 14f8a6b..f07f593 100644 --- a/tck/src/test/resources/org/objenesis/tck/CandidateLoaderTest-sample.properties +++ b/tck/src/test/resources/org/objenesis/tck/CandidateLoaderTest-sample.properties @@ -1,5 +1,5 @@ # -# Copyright 2006-2013 the original author or authors. +# Copyright 2006-2017 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,43 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# 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. -# -# 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. -# -# 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. -# -# See CandidateLoaderTest.java +# See CandidateLoaderTest.java org.objenesis.tck.CandidateLoaderTest$A = A candidate org.objenesis.tck.CandidateLoaderTest$B = B candidate
\ No newline at end of file diff --git a/tck/test/log4j.properties b/tck/test/log4j.properties deleted file mode 100644 index 5a5db6b..0000000 --- a/tck/test/log4j.properties +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright 2006-2013 the original author or authors. -# -# 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. -# -# 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. -# -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout.ConversionPattern=%p [%c] - %m%n -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout - -log4j.rootCategory=WARN, stdout - -# Uncomment to add logs -#log4j.logger.org.easymock.itests.OsgiTest=TRACE, stdout |