Merge branch osgiR8 into master
diff --git a/bundles/org.eclipse.osgi.compatibility.state/.classpath b/bundles/org.eclipse.osgi.compatibility.state/.classpath
index 098194c..eca7bdb 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/.classpath
+++ b/bundles/org.eclipse.osgi.compatibility.state/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
diff --git a/bundles/org.eclipse.osgi.compatibility.state/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi.compatibility.state/.settings/org.eclipse.jdt.core.prefs
index 4b36b50..d36025c 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi.compatibility.state/.settings/org.eclipse.jdt.core.prefs
@@ -16,9 +16,9 @@
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -124,23 +124,27 @@
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
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_bitwise_operator=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_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=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_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
@@ -210,11 +214,12 @@
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_additive_operator=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_bitwise_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
@@ -244,6 +249,8 @@
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_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=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
@@ -267,12 +274,16 @@
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_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=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_bitwise_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
@@ -318,6 +329,8 @@
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_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=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
@@ -353,8 +366,11 @@
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_relational_operator=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_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=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
@@ -377,6 +393,10 @@
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
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_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.osgi.compatibility.state/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.compatibility.state/META-INF/MANIFEST.MF
index 7f51a90..6153f31 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.compatibility.state/META-INF/MANIFEST.MF
@@ -2,9 +2,9 @@
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.osgi.compatibility.state
-Bundle-Version: 1.1.800.qualifier
+Bundle-Version: 1.2.0.qualifier
ExtensionBundle-Activator: org.eclipse.osgi.compatibility.state.Activator
Fragment-Host: org.eclipse.osgi;bundle-version="3.12.0"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: %Bundle-Vendor
Automatic-Module-Name: org.eclipse.osgi.compatibility.state
diff --git a/bundles/org.eclipse.osgi.compatibility.state/pom.xml b/bundles/org.eclipse.osgi.compatibility.state/pom.xml
index a0276f1..cb3b877 100644
--- a/bundles/org.eclipse.osgi.compatibility.state/pom.xml
+++ b/bundles/org.eclipse.osgi.compatibility.state/pom.xml
@@ -19,6 +19,6 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.compatibility.state</artifactId>
- <version>1.1.800-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.osgi.services/.settings/.api_filters b/bundles/org.eclipse.osgi.services/.settings/.api_filters
index 628261d..1f4a3ae 100644
--- a/bundles/org.eclipse.osgi.services/.settings/.api_filters
+++ b/bundles/org.eclipse.osgi.services/.settings/.api_filters
@@ -1,497 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.osgi.services" version="2">
<resource path="META-INF/MANIFEST.MF">
- <filter comment="Ignore OSGI API" id="923795461">
+ <filter comment="Semantics of log package changed and package version increased." id="926941240">
<message_arguments>
+ <message_argument value="3.9.0"/>
<message_argument value="3.8.0"/>
- <message_argument value="3.7.100"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/Configuration.java" type="org.osgi.service.cm.Configuration">
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.Configuration"/>
- <message_argument value="addAttributes(Configuration.ConfigurationAttribute[])"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.Configuration"/>
- <message_argument value="getAttributes()"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.Configuration"/>
- <message_argument value="getProcessedProperties(ServiceReference<?>)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.Configuration"/>
- <message_argument value="removeAttributes(Configuration.ConfigurationAttribute[])"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.Configuration"/>
- <message_argument value="updateIfDifferent(Dictionary<String,?>)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="addAttributes(Configuration.ConfigurationAttribute[])"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="getAttributes()"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="getProcessedProperties(ServiceReference<?>)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="removeAttributes(Configuration.ConfigurationAttribute[])"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="updateIfDifferent(Dictionary<String,?>)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/Configuration.java" type="org.osgi.service.cm.Configuration$ConfigurationAttribute">
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="ConfigurationAttribute"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/ConfigurationAdmin.java" type="org.osgi.service.cm.ConfigurationAdmin">
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.ConfigurationAdmin"/>
- <message_argument value="getFactoryConfiguration(String, String)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="403804204">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.ConfigurationAdmin"/>
- <message_argument value="getFactoryConfiguration(String, String, String)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="getFactoryConfiguration(String, String)"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1209008130">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="getFactoryConfiguration(String, String, String)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/ConfigurationConstants.java" type="org.osgi.service.cm.ConfigurationConstants">
- <filter comment="Ignore OSGi API" id="1110441988">
- <message_arguments>
- <message_argument value="org.osgi.service.cm.ConfigurationConstants"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/ConfigurationPermission.java" type="org.osgi.service.cm.ConfigurationPermission">
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="ATTRIBUTE"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/cm/ReadOnlyConfigurationException.java" type="org.osgi.service.cm.ReadOnlyConfigurationException">
- <filter comment="Ignore OSGi API" id="1108344834">
- <message_arguments>
- <message_argument value="1.6"/>
- <message_argument value="3.8"/>
- <message_argument value="org.osgi.service.cm.ReadOnlyConfigurationException"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/component/ComponentConstants.java" type="org.osgi.service.component.ComponentConstants">
- <filter comment="Ignore OSGI API" id="403767336">
- <message_arguments>
- <message_argument value="org.osgi.service.component.ComponentConstants"/>
- <message_argument value="COMPONENT_SPECIFICATION_VERSION"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1209008130">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="COMPONENT_SPECIFICATION_VERSION"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/component/runtime/dto/ComponentConfigurationDTO.java" type="org.osgi.service.component.runtime.dto.ComponentConfigurationDTO">
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentConfigurationDTO"/>
- <message_argument value="FAILED_ACTIVATION"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentConfigurationDTO"/>
- <message_argument value="failure"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentConfigurationDTO"/>
- <message_argument value="service"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="FAILED_ACTIVATION"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="failure"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="service"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/component/runtime/dto/ComponentDescriptionDTO.java" type="org.osgi.service.component.runtime.dto.ComponentDescriptionDTO">
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentDescriptionDTO"/>
- <message_argument value="activationFields"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentDescriptionDTO"/>
- <message_argument value="factoryProperties"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ComponentDescriptionDTO"/>
- <message_argument value="init"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="activationFields"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="factoryProperties"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="init"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/component/runtime/dto/ReferenceDTO.java" type="org.osgi.service.component.runtime.dto.ReferenceDTO">
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ReferenceDTO"/>
- <message_argument value="collectionType"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.component.runtime.dto.ReferenceDTO"/>
- <message_argument value="parameter"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="collectionType"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGI API" id="1141899266">
- <message_arguments>
- <message_argument value="1.4"/>
- <message_argument value="3.8"/>
- <message_argument value="parameter"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/context/ServletContextHelper.java" type="org.osgi.service.http.context.ServletContextHelper">
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="finishSecurity(HttpServletRequest, HttpServletResponse)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/runtime/dto/DTOConstants.java" type="org.osgi.service.http.runtime.dto.DTOConstants">
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="FAILURE_REASON_SERVLET_READ_FROM_DEFAULT_DENIED"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="FAILURE_REASON_SERVLET_WRITE_TO_LOCATION_DENIED"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="FAILURE_REASON_WHITEBOARD_WRITE_TO_DEFAULT_DENIED"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="FAILURE_REASON_WHITEBOARD_WRITE_TO_LOCATION_DENIED"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/runtime/dto/FailedPreprocessorDTO.java" type="org.osgi.service.http.runtime.dto.FailedPreprocessorDTO">
- <filter comment="Ignore OSGi API" id="1108344834">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="org.osgi.service.http.runtime.dto.FailedPreprocessorDTO"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/runtime/dto/PreprocessorDTO.java" type="org.osgi.service.http.runtime.dto.PreprocessorDTO">
- <filter comment="Ignore OSGi API" id="1108344834">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="org.osgi.service.http.runtime.dto.PreprocessorDTO"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/runtime/dto/RuntimeDTO.java" type="org.osgi.service.http.runtime.dto.RuntimeDTO">
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.RuntimeDTO"/>
- <message_argument value="failedPreprocessorDTOs"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.RuntimeDTO"/>
- <message_argument value="preprocessorDTOs"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="failedPreprocessorDTOs"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="preprocessorDTOs"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/runtime/dto/ServletDTO.java" type="org.osgi.service.http.runtime.dto.ServletDTO">
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.ServletDTO"/>
- <message_argument value="multipartEnabled"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.ServletDTO"/>
- <message_argument value="multipartFileSizeThreshold"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.ServletDTO"/>
- <message_argument value="multipartLocation"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.ServletDTO"/>
- <message_argument value="multipartMaxFileSize"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="336658481">
- <message_arguments>
- <message_argument value="org.osgi.service.http.runtime.dto.ServletDTO"/>
- <message_argument value="multipartMaxRequestSize"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="multipartEnabled"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="multipartFileSizeThreshold"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="multipartLocation"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="multipartMaxFileSize"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="multipartMaxRequestSize"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/whiteboard/HttpWhiteboardConstants.java" type="org.osgi.service.http.whiteboard.HttpWhiteboardConstants">
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_SERVICE_CONTEXT_FILTER"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_SERVICE_CONTEXT_PROPERTY"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_IMPLEMENTATION"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_PREPROCESSOR_INIT_PARAM_PREFIX"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SERVLET_MULTIPART_ENABLED"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SERVLET_MULTIPART_FILESIZETHRESHOLD"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SERVLET_MULTIPART_LOCATION"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SERVLET_MULTIPART_MAXFILESIZE"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SERVLET_MULTIPART_MAXREQUESTSIZE"/>
- </message_arguments>
- </filter>
- <filter comment="Ignore OSGi API" id="1141899266">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="HTTP_WHITEBOARD_SPECIFICATION_VERSION"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/osgi/service/http/whiteboard/Preprocessor.java" type="org.osgi.service.http.whiteboard.Preprocessor">
- <filter comment="Ignore OSGi API" id="1108344834">
- <message_arguments>
- <message_argument value="1.1"/>
- <message_argument value="3.8"/>
- <message_argument value="org.osgi.service.http.whiteboard.Preprocessor"/>
</message_arguments>
</filter>
</resource>
diff --git a/bundles/org.eclipse.osgi.services/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi.services/.settings/org.eclipse.jdt.core.prefs
index 0b08c18..c352a71 100644
--- a/bundles/org.eclipse.osgi.services/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi.services/.settings/org.eclipse.jdt.core.prefs
@@ -9,8 +9,11 @@
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
@@ -21,6 +24,8 @@
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@@ -66,12 +71,14 @@
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
@@ -86,21 +93,28 @@
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
diff --git a/bundles/org.eclipse.osgi.services/.settings/org.eclipse.pde.api.tools.prefs b/bundles/org.eclipse.osgi.services/.settings/org.eclipse.pde.api.tools.prefs
index e2758b7..fa3737c 100644
--- a/bundles/org.eclipse.osgi.services/.settings/org.eclipse.pde.api.tools.prefs
+++ b/bundles/org.eclipse.osgi.services/.settings/org.eclipse.pde.api.tools.prefs
@@ -94,7 +94,7 @@
eclipse.preferences.version=1
incompatible_api_component_version=Error
incompatible_api_component_version_report_major_without_breaking_change=Warning
-incompatible_api_component_version_report_minor_without_api_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Error
invalid_since_tag_version=Error
malformed_since_tag=Error
missing_since_tag=Error
diff --git a/bundles/org.eclipse.osgi.services/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.services/META-INF/MANIFEST.MF
index 5129383..79ba75f 100644
--- a/bundles/org.eclipse.osgi.services/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.services/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %osgiServices
Bundle-SymbolicName: org.eclipse.osgi.services
-Bundle-Version: 3.8.0.qualifier
+Bundle-Version: 3.9.0.qualifier
Bundle-Description: %osgiServicesDes
Bundle-Localization: plugin
Bundle-Vendor: %eclipse.org
@@ -20,7 +20,7 @@
org.osgi.service.http.runtime;version="1.1";uses:="org.osgi.service.http.runtime.dto",
org.osgi.service.http.runtime.dto;version="1.1";uses:="org.osgi.dto,org.osgi.framework.dto",
org.osgi.service.http.whiteboard;version="1.1",
- org.osgi.service.log;version="1.4";uses:="org.osgi.framework",
+ org.osgi.service.log;version="1.5";uses:="org.osgi.framework",
org.osgi.service.metatype;version="1.4";uses:="org.osgi.framework",
org.osgi.service.provisioning;version="1.2",
org.osgi.service.upnp;version="1.2",
@@ -43,7 +43,7 @@
org.osgi.service.http.runtime;version="[1.1,1.2)",
org.osgi.service.http.runtime.dto;version="[1.1,1.2)",
org.osgi.service.http.whiteboard;version="[1.1,1.2)",
- org.osgi.service.log;version="[1.4,1.5)",
+ org.osgi.service.log;version="[1.5,1.6)",
org.osgi.service.metatype;version="[1.4,1.5)",
org.osgi.service.provisioning;version="[1.2,1.3)",
org.osgi.service.upnp;version="[1.2,1.3)",
diff --git a/bundles/org.eclipse.osgi.services/pom.xml b/bundles/org.eclipse.osgi.services/pom.xml
index 63eaa42..c757ef1 100644
--- a/bundles/org.eclipse.osgi.services/pom.xml
+++ b/bundles/org.eclipse.osgi.services/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
- <version>3.8.0-SNAPSHOT</version>
+ <version>3.9.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
diff --git a/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java b/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java
index 55d1069..b5b08d7 100644
--- a/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java
+++ b/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,9 +75,11 @@
* The {@code ServiceReference} field and the {@code Throwable} field of the
* {@code LogEntry} object will be set to {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -105,9 +107,11 @@
* The {@code ServiceReference} field of the {@code LogEntry} object will be
* set to {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -138,9 +142,11 @@
* The {@code Throwable} field of the {@code LogEntry} will be set to
* {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -168,9 +174,11 @@
* Logs a message with an exception associated and a
* {@code ServiceReference} object.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
diff --git a/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/package-info.java b/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/package-info.java
index 81c287a..b053188 100644
--- a/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/package-info.java
+++ b/bundles/org.eclipse.osgi.services/src/org/osgi/service/log/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
*/
/**
- * Log Service Package Version 1.4.
+ * Log Service Package Version 1.5.
* <p>
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
@@ -24,15 +24,15 @@
* <p>
* Example import for consumers using the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.log; version="[1.4,2.0)"}
+ * {@code Import-Package: org.osgi.service.log; version="[1.5,2.0)"}
* <p>
* Example import for providers implementing the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.log; version="[1.4,1.5)"}
+ * {@code Import-Package: org.osgi.service.log; version="[1.5,1.6)"}
*
* @author $Id$
*/
-@Version("1.4")
+@Version("1.5")
package org.osgi.service.log;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath
index cc89595..2d89fd7 100644
--- a/bundles/org.eclipse.osgi.tests/.classpath
+++ b/bundles/org.eclipse.osgi.tests/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="bundle_tests/test" path="bundles_src/test"/>
@@ -112,6 +112,7 @@
<classpathentry kind="src" output="bundle_tests/geturl" path="bundles_src/geturl"/>
<classpathentry kind="src" output="bundle_tests/test.bug375784" path="bundles_src/test.bug375784"/>
<classpathentry kind="src" output="bundle_tests/storage.hooks.a" path="bundles_src/storage.hooks.a"/>
+ <classpathentry kind="src" output="bundle_tests/activator.hooks.a" path="bundles_src/activator.hooks.a"/>
<classpathentry kind="src" output="bundle_tests/test.bug412228" path="bundles_src/test.bug412228"/>
<classpathentry kind="src" output="bundle_tests/test.uninstall.start1" path="bundles_src/test.uninstall.start1"/>
<classpathentry kind="src" output="bundle_tests/test.uninstall.start2" path="bundles_src/test.uninstall.start2"/>
diff --git a/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
index d607898..25c2151 100644
--- a/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi.tests/.settings/org.eclipse.jdt.core.prefs
@@ -17,9 +17,9 @@
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -131,7 +131,7 @@
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
index f59d996..fb97223 100644
--- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Core OSGi Tests
Bundle-SymbolicName: org.eclipse.osgi.tests;singleton:=true
-Bundle-Version: 3.15.400.qualifier
+Bundle-Version: 3.16.0.qualifier
Bundle-Vendor: Eclipse.org
Require-Bundle:
org.eclipse.core.runtime,
@@ -14,7 +14,7 @@
Import-Package: org.osgi.service.event; resolution:="optional"
Export-Package: org.eclipse.osgi.tests.bundles,
org.eclipse.osgi.tests.appadmin
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
DynamicImport-Package: ext.framework.b
Eclipse-BundleShape: dir
Automatic-Module-Name: org.eclipse.osgi.tests
diff --git a/bundles/org.eclipse.osgi.tests/build.properties b/bundles/org.eclipse.osgi.tests/build.properties
index 0054cac..91c0b2d 100644
--- a/bundles/org.eclipse.osgi.tests/build.properties
+++ b/bundles/org.eclipse.osgi.tests/build.properties
@@ -239,6 +239,8 @@
manifest.bundle_tests/test.bug375784.jar = META-INF/MANIFEST.MF
source.bundle_tests/storage.hooks.a.jar = bundles_src/storage.hooks.a/
manifest.bundle_tests/storage.hooks.a.jar = META-INF/MANIFEST.MF
+source.bundle_tests/activator.hooks.a.jar = bundles_src/activator.hooks.a/
+manifest.bundle_tests/activator.hooks.a.jar = META-INF/MANIFEST.MF
source.bundle_tests/test.bug412228.jar = bundles_src/test.bug412228/
manifest.bundle_tests/test.bug412228.jar = META-INF/MANIFEST.MF
source.bundle_tests/test.uninstall.start1.jar = bundles_src/test.uninstall.start1/
@@ -388,6 +390,7 @@
bundle_tests/geturl.jar,\
bundle_tests/test.bug375784.jar,\
bundle_tests/storage.hooks.a.jar,\
+ bundle_tests/activator.hooks.a.jar,\
bundle_tests/test.plugins.a.jar,\
bundle_tests/test.plugins.b.jar,\
bundle_tests/test.plugins.c.jar,\
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9ced5b5
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: activator.hooks.a
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator1.java b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator1.java
new file mode 100644
index 0000000..1c1057f
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator1.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.hooks.framework.activator.a;
+
+import java.util.List;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class TestHookConfigurator1 implements HookConfigurator {
+
+ public static volatile List<String> events;
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
+
+ @Override
+ public BundleActivator createActivator() {
+ return new BundleActivator() {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK1 STARTED");
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK1 STOPPED");
+ }
+ }
+ };
+ }
+ });
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator2.java b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator2.java
new file mode 100644
index 0000000..b9724a5
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator2.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.hooks.framework.activator.a;
+
+import java.util.List;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class TestHookConfigurator2 implements HookConfigurator {
+ public static volatile List<String> events;
+
+ @Override
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
+
+ @Override
+ public BundleActivator createActivator() {
+ return new BundleActivator() {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK2 STARTED");
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK2 STOPPED");
+ }
+ }
+ };
+ }
+ });
+
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator3.java b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator3.java
new file mode 100644
index 0000000..85e2bfe
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/activator.hooks.a/org/eclipse/osgi/tests/hooks/framework/activator/a/TestHookConfigurator3.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.hooks.framework.activator.a;
+
+import java.util.List;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class TestHookConfigurator3 implements HookConfigurator {
+ public static volatile List<String> events;
+
+ @Override
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
+
+ @Override
+ public BundleActivator createActivator() {
+ return new BundleActivator() {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK3 STARTED");
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (events != null) {
+ events.add("HOOK3 STOPPED");
+ }
+ }
+ };
+ }
+ });
+
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.importer/ext/framework/a/importer/Activator.java b/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.importer/ext/framework/a/importer/Activator.java
index e85f335..367c27c 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.importer/ext/framework/a/importer/Activator.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.importer/ext/framework/a/importer/Activator.java
@@ -14,9 +14,12 @@
package ext.framework.a.importer;
import ext.framework.a.FrameworkExtTest;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.URL;
import org.eclipse.osgi.tests.bundles.AbstractBundleTests;
+import org.eclipse.osgi.tests.bundles.ExtensionBundleTests;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -25,6 +28,7 @@
public void start(BundleContext context) throws Exception {
AbstractBundleTests.simpleResults.addEvent(new FrameworkExtTest().testIt("success")); //$NON-NLS-1$
AbstractBundleTests.simpleResults.addEvent(getURLContent(this.getClass().getResource("/ext/framework/a/fwkresource.txt"))); //$NON-NLS-1$
+ ExtensionBundleTests.events.add(context.getBundle().getSymbolicName() + " STARTED");
}
private String getURLContent(URL resource) throws IOException {
@@ -37,7 +41,7 @@
}
public void stop(BundleContext context) throws Exception {
- // nothing
+ ExtensionBundleTests.events.add(context.getBundle().getSymbolicName() + " STOPPED");
}
}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.requires/ext/framework/a/requires/Activator.java b/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.requires/ext/framework/a/requires/Activator.java
index 09a88fd..7367f0a 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.requires/ext/framework/a/requires/Activator.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/ext.framework.a.requires/ext/framework/a/requires/Activator.java
@@ -14,9 +14,12 @@
package ext.framework.a.requires;
import ext.framework.a.FrameworkExtTest;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.URL;
import org.eclipse.osgi.tests.bundles.AbstractBundleTests;
+import org.eclipse.osgi.tests.bundles.ExtensionBundleTests;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -25,6 +28,7 @@
public void start(BundleContext context) throws Exception {
AbstractBundleTests.simpleResults.addEvent(new FrameworkExtTest().testIt("success")); //$NON-NLS-1$
AbstractBundleTests.simpleResults.addEvent(getURLContent(this.getClass().getResource("/ext/framework/a/fwkresource.txt"))); //$NON-NLS-1$
+ ExtensionBundleTests.events.add(context.getBundle().getSymbolicName() + " STARTED");
}
private String getURLContent(URL resource) throws IOException {
@@ -37,7 +41,7 @@
}
public void stop(BundleContext context) throws Exception {
- // nothing
+ ExtensionBundleTests.events.add(context.getBundle().getSymbolicName() + " STOPPED");
}
}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
similarity index 98%
rename from bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper
rename to bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
index a3365b5..875f91c 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper
@@ -1 +1 @@
-org.eclipse.osgi.tests.hooks.framework.storage.a.TestHelper
\ No newline at end of file
+org.eclipse.osgi.tests.hooks.framework.storage.a.TestHelper
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
index 35b949c..639865e 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHelper.java
@@ -13,14 +13,19 @@
*******************************************************************************/
package org.eclipse.osgi.tests.hooks.framework.storage.a;
-import org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper;
+import java.util.Optional;
import org.osgi.framework.Bundle;
+import org.osgi.framework.connect.FrameworkUtilHelper;
-public class TestHelper extends FrameworkUtilHelper {
- volatile static Bundle testBundle = null;
+public class TestHelper implements FrameworkUtilHelper {
+ volatile static Bundle testBundle;
@Override
- public Bundle getBundle(Class<?> classFromBundle) {
- return testBundle;
+ public Optional<Bundle> getBundle(Class<?> classFromBundle) {
+ return Optional.ofNullable(testBundle);
+ }
+
+ public static void setBundle(Bundle testBundle) {
+ TestHelper.testBundle = testBundle;
}
}
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
index aa29bef..d25cb8a 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java
@@ -184,15 +184,14 @@
@Override
public BundleActivator createActivator() {
return new BundleActivator() {
-
@Override
public void start(BundleContext context) throws Exception {
- TestHelper.testBundle = context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
+ TestHelper.setBundle(context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION));
}
@Override
public void stop(BundleContext context) throws Exception {
- // nothing
+ TestHelper.setBundle(null);
}
};
}
diff --git a/bundles/org.eclipse.osgi.tests/pom.xml b/bundles/org.eclipse.osgi.tests/pom.xml
index 1972767..09698e8 100644
--- a/bundles/org.eclipse.osgi.tests/pom.xml
+++ b/bundles/org.eclipse.osgi.tests/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.tests</artifactId>
- <version>3.15.400-SNAPSHOT</version>
+ <version>3.16.0-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/AbstractBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/AbstractBundleTests.java
index 75b74e3..10a06ad 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/AbstractBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/AbstractBundleTests.java
@@ -360,6 +360,23 @@
return waitForStop(equinox, uuid, quietly, timeout);
}
+ protected static boolean delete(File file) {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ String list[] = file.list();
+ if (list != null) {
+ int len = list.length;
+ for (int i = 0; i < len; i++) {
+ delete(new File(file, list[i]));
+ }
+ }
+ }
+
+ return file.delete();
+ }
+ return (true);
+ }
+
static public FrameworkEvent waitForStop(Framework equinox, String uuid, boolean quietly, long timeout) {
try {
FrameworkEvent stopEvent = equinox.waitForStop(timeout);
@@ -407,4 +424,4 @@
return "UNKNOWN:" + state;
}
}
-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
index e955a5c..9805426 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleTests.java
@@ -19,6 +19,7 @@
public class BundleTests {
public static Test suite() {
TestSuite suite = new TestSuite(BundleTests.class.getName());
+ suite.addTest(ConnectTests.suite());
suite.addTest(ExceptionMessageTest.suite());
suite.addTest(ImportJavaSEPackagesTests.suite());
suite.addTest(MultiReleaseJarTests.suite());
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java
new file mode 100644
index 0000000..c84ab16
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java
@@ -0,0 +1,1035 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles;
+
+import static org.junit.Assert.assertNotEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.eclipse.osgi.container.ModuleContainer;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.eclipse.osgi.launch.EquinoxFactory;
+import org.eclipse.osgi.tests.OSGiTestsActivator;
+import org.eclipse.osgi.tests.bundles.classes.Activator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectContent.ConnectEntry;
+import org.osgi.framework.connect.ConnectFrameworkFactory;
+import org.osgi.framework.connect.ConnectModule;
+import org.osgi.framework.connect.ModuleConnector;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.FrameworkWiring;
+import org.osgi.resource.Namespace;
+import org.osgi.service.condition.Condition;
+
+public class ConnectTests extends AbstractBundleTests {
+
+ public static Test suite() {
+ return new TestSuite(ConnectTests.class);
+ }
+
+ void cleanStorage() {
+ delete(getContext().getDataFile(getName()));
+ }
+
+ void doTestConnect(ModuleConnector moduleConnector, Map<String, String> fwkConfig, Consumer<Framework> test) {
+ doTestConnect(moduleConnector, fwkConfig, test, false);
+ }
+
+ void doTestConnect(ModuleConnector moduleConnector, Map<String, String> fwkConfig, Consumer<Framework> test,
+ boolean enableRuntimeVerification) {
+ File config = OSGiTestsActivator.getContext().getDataFile(getName());
+ config.mkdirs();
+ fwkConfig = new HashMap<>(fwkConfig);
+ fwkConfig.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath());
+ if (enableRuntimeVerification) {
+ fwkConfig.put("osgi.signedcontent.support", "runtime");
+ }
+ ConnectFrameworkFactory fwkFactory = new EquinoxFactory();
+ Framework framework = fwkFactory.newFramework(fwkConfig, moduleConnector);
+ boolean passed = false;
+ try {
+ test.accept(framework);
+ passed = true;
+ } finally {
+ try {
+ framework.stop();
+ framework.waitForStop(10000);
+ } catch (Exception e) {
+ if (passed) {
+ sneakyThrow(e);
+ }
+ }
+ }
+ }
+
+ public static class TestCountingModuleConnector implements ModuleConnector {
+ private final AtomicInteger initializeCalled = new AtomicInteger();
+ private final Queue<String> getModuleCalled = new ConcurrentLinkedQueue<>();
+ private final AtomicInteger createBundleActivatorCalled = new AtomicInteger();
+ private final Map<String, ConnectModule> modules = new ConcurrentHashMap<>();
+
+ @Override
+ public void initialize(File storage, Map<String, String> config) {
+ initializeCalled.getAndIncrement();
+ }
+
+ @Override
+ public Optional<ConnectModule> connect(String location) throws BundleException {
+ getModuleCalled.add(location);
+ ConnectModule m = modules.get(location);
+ if (m == BUNDLE_EXCEPTION) {
+ throw new BundleException("Test fail install with getModule");
+ }
+ return Optional.ofNullable(m);
+ }
+
+ @Override
+ public Optional<BundleActivator> newBundleActivator() {
+ createBundleActivatorCalled.getAndIncrement();
+ return Optional.empty();
+ }
+
+ int getInitializeCnt() {
+ return initializeCalled.get();
+ }
+
+ List<String> getModuleLocations() {
+ return new ArrayList<>(getModuleCalled);
+ }
+
+ int getCreateBundleActivatorCnt() {
+ return createBundleActivatorCalled.get();
+ }
+
+ void setModule(String location, ConnectModule module) {
+ if (module == null) {
+ modules.remove(location);
+ } else {
+ modules.put(location, module);
+ }
+ }
+ }
+
+ public static class TestConnectModule implements ConnectModule {
+ private volatile TestConnectContent content;
+
+ public TestConnectModule(TestConnectContent content) {
+ this.content = content;
+ }
+
+ @Override
+ public TestConnectContent getContent() {
+ return content;
+ }
+
+ void setContent(TestConnectContent updatedContent) {
+ this.content = updatedContent;
+ }
+ }
+
+ public static class TestConnectContent implements ConnectContent {
+ private final Map<String, String> headers;
+ private final Map<String, ConnectEntry> entries = new LinkedHashMap<>();
+ private final ClassLoader loader;
+ private final AtomicBoolean isOpen = new AtomicBoolean();
+
+ public TestConnectContent(Map<String, String> headers, ClassLoader loader) {
+ this.headers = headers;
+ this.loader = loader;
+ }
+
+ @Override
+ public Optional<Map<String, String>> getHeaders() {
+ checkOpen();
+ return Optional.ofNullable(headers);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public Iterable<String> getEntries() throws IOException {
+ checkOpen();
+ return entries.keySet();
+ }
+
+ @Override
+ public Optional<ConnectEntry> getEntry(String name) {
+ checkOpen();
+ return Optional.ofNullable(entries.get(name));
+ }
+
+ @Override
+ public Optional<ClassLoader> getClassLoader() {
+ checkOpen();
+ return Optional.ofNullable(loader);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void open() throws IOException {
+ if (!isOpen.compareAndSet(false, true)) {
+ throw new IllegalStateException("Already Opened.");
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public void close() throws IOException {
+ if (!isOpen.compareAndSet(true, false)) {
+ throw new IllegalStateException("Already Closed.");
+ }
+ }
+
+ void addEntry(String path, ConnectEntry entry) {
+ entries.put(path, entry);
+ }
+
+ private void checkOpen() {
+ if (!isOpen.get()) {
+ throw new IllegalStateException("Not Opened.");
+ }
+ }
+
+ boolean isOpen() {
+ return isOpen.get();
+ }
+ }
+
+ public static class TestConnectEntryBytes implements ConnectEntry {
+ private final String name;
+ private final byte[] bytes;
+
+ public TestConnectEntryBytes(String name, byte[] bytes) {
+ this.name = name;
+ this.bytes = bytes;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public long getContentLength() {
+ return bytes.length;
+ }
+
+ @Override
+ public long getLastModified() {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes() {
+ return bytes.clone();
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ }
+
+ public static class TestConnectEntryURL implements ConnectEntry {
+ private final String name;
+ private final URL content;
+
+ public TestConnectEntryURL(String name, URL content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public long getContentLength() {
+ try {
+ return content.openConnection().getContentLengthLong();
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ @Override
+ public long getLastModified() {
+ try {
+ return content.openConnection().getLastModified();
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return content.openStream();
+ }
+
+ }
+
+ static final TestConnectModule BUNDLE_EXCEPTION = new TestConnectModule(null);
+
+ public void testConnectFactoryNoModules() {
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+
+ assertEquals("Wrong number of init called.", 2, connector.getInitializeCnt());
+ assertEquals("Wrong number of create activator called.", 3, connector.getCreateBundleActivatorCnt());
+ }
+
+ public void testConnectActivator() {
+ final AtomicInteger bundleActvatorStartCalled = new AtomicInteger();
+ final AtomicInteger bundleActvatorStopCalled = new AtomicInteger();
+ ModuleConnector activatorModuleConnector = new TestCountingModuleConnector() {
+ @Override
+ public Optional<BundleActivator> newBundleActivator() {
+ super.newBundleActivator();
+ return Optional.of(new BundleActivator() {
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ bundleActvatorStartCalled.getAndIncrement();
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ bundleActvatorStopCalled.getAndIncrement();
+ }
+ });
+ }
+ };
+
+ doTestConnect(activatorModuleConnector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ f.start();
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Exception e) {
+ sneakyThrow(e);
+ }
+ });
+ assertEquals("Wrong number of start called.", 2, bundleActvatorStartCalled.get());
+ assertEquals("Wrong number of stop called.", 2, bundleActvatorStopCalled.get());
+ }
+
+ public void testTrueCondition() {
+ final AtomicReference<ServiceReference<Condition>> trueConditionStart = new AtomicReference<>();
+ final AtomicReference<ServiceReference<Condition>> trueConditionStop = new AtomicReference<>();
+
+ ModuleConnector activatorModuleConnector = new TestCountingModuleConnector() {
+ @Override
+ public Optional<BundleActivator> newBundleActivator() {
+ super.newBundleActivator();
+ return Optional.of(new BundleActivator() {
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ trueConditionStart.set(context
+ .getServiceReferences(Condition.class,
+ '(' + Condition.CONDITION_ID + '=' + Condition.CONDITION_ID_TRUE + ')')
+ .iterator().next());
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ trueConditionStop.set(context
+ .getServiceReferences(Condition.class,
+ '(' + Condition.CONDITION_ID + '=' + Condition.CONDITION_ID_TRUE + ')')
+ .iterator().next());
+ }
+ });
+ }
+ };
+
+ doTestConnect(activatorModuleConnector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ ServiceReference<Condition> trueCondition = trueConditionStart.get();
+ assertNotNull("No true condition found.", trueCondition);
+ assertEquals("Wrong bundle.", f.getBundleContext().getBundle(), trueCondition.getBundle());
+ f.stop();
+ f.waitForStop(5000);
+
+ assertEquals("Different true condition found on start and stop.", trueCondition,
+ trueConditionStop.get());
+ assertNull("True condition should be unregistered on stop.", trueCondition.getBundle());
+
+ } catch (Exception e) {
+ sneakyThrow(e);
+ }
+ });
+ }
+
+ public void testConnectInit() {
+ final AtomicReference<File> initFile = new AtomicReference<>();
+ final AtomicReference<File> storeFile = new AtomicReference<>();
+ final AtomicReference<Map<String, String>> initConfig = new AtomicReference<>();
+ ModuleConnector initParamsModuleConnector = new TestCountingModuleConnector() {
+ @Override
+ public void initialize(File storage, Map<String, String> config) {
+ super.initialize(storage, config);
+ initFile.set(storage);
+ initConfig.set(config);
+ }
+ };
+
+ Map<String, String> config = new HashMap<>();
+ config.put("k1", "v1");
+ config.put("k2", "v2");
+
+ doTestConnect(initParamsModuleConnector, config, (f) -> {
+ try {
+ f.init();
+ BundleContext bc = f.getBundleContext();
+ storeFile.set(new File(bc.getProperty(Constants.FRAMEWORK_STORAGE)));
+ } catch (Exception e) {
+ sneakyThrow(e);
+ }
+ });
+ TestCase.assertEquals("Wrong init store file.", storeFile.get(), initFile.get());
+ assertTrue("Did not find all init configs: " + initConfig.get(),
+ initConfig.get().entrySet().containsAll(config.entrySet()));
+ try {
+ initConfig.get().put("k3", "v3");
+ fail("Expected unmodifiable map");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testConnectContentHeaders() throws IOException {
+ doTestConnectContentSimple(false);
+ }
+
+ public void testConnectContentManifest() throws IOException {
+ doTestConnectContentSimple(true);
+ }
+
+ void doTestConnectContentSimple(boolean withManifest) throws IOException {
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ final List<String> locations = Arrays.asList("b.1", "b.2", "b.3", "b.4");
+ for (String l : locations) {
+ connector.setModule(l, withManifest ? createSimpleManifestModule(l) : createSimpleHeadersModule(l));
+ }
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.init();
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().installBundle(l);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ checkConnectTag(b);
+ }
+ checkConnectTags(f, locations);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.init();
+ Bundle[] bundles = f.getBundleContext().getBundles();
+ assertEquals("Wrong number of bundles from cache.", locations.size() + 1, bundles.length);
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().getBundle(l);
+ assertNotNull("No bundle at location: " + l, b);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ checkConnectTag(b);
+ checkConnectTags(f, locations);
+ }
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+
+ connector.setModule("b.2", null);
+ connector.setModule("b.3", BUNDLE_EXCEPTION);
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.init();
+ Bundle[] bundles = f.getBundleContext().getBundles();
+ assertEquals("Wrong number of bundles from cache.", locations.size() - 1, bundles.length);
+ for (String l : locations) {
+ Bundle b = f.getBundleContext().getBundle(l);
+ if ("b.2".equals(l) || "b.3".equals(l)) {
+ assertNull("Found unexpected bundle.", b);
+ } else {
+ assertNotNull("No bundle at location: " + l, b);
+ assertEquals("Wrong symbolic name.", l, b.getSymbolicName());
+ checkConnectTag(b);
+ }
+ }
+ } catch (BundleException e) {
+ sneakyThrow(e);
+ }
+ });
+ }
+
+ private static void checkConnectTag(Bundle b) {
+ final List<String> namespaces = new ArrayList<>(Arrays.asList(BundleNamespace.BUNDLE_NAMESPACE,
+ HostNamespace.HOST_NAMESPACE, IdentityNamespace.IDENTITY_NAMESPACE));
+
+ b.adapt(BundleRevision.class).getCapabilities(null).stream().filter(c -> namespaces.contains(c.getNamespace()))
+ .forEach(c -> {
+ List<String> tags = (List<String>) c.getAttributes()
+ .get(IdentityNamespace.CAPABILITY_TAGS_ATTRIBUTE);
+ assertNotNull("No tags found.", tags);
+ assertEquals("Wrong number of tags.", 1, tags.size());
+ assertTrue("Connect tag not found.", tags.contains(ConnectContent.TAG_OSGI_CONNECT));
+ namespaces.remove(c.getNamespace());
+ });
+ assertTrue("Connect tag namespaces were not removed completely. Found " + namespaces, namespaces.isEmpty());
+ }
+
+ private static void checkConnectTags(Framework f, List<String> locations) {
+ Collection<BundleCapability> osgiConnectTags = f.adapt(FrameworkWiring.class).findProviders( //
+ ModuleContainer.createRequirement(IdentityNamespace.IDENTITY_NAMESPACE, //
+ Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(tags=osgi.connect)"), //
+ Collections.emptyMap()));
+ osgiConnectTags.forEach(c -> {
+ assertTrue("Unexpected tag on bundle: " + c.getRevision().getBundle(),
+ locations.contains(c.getRevision().getBundle().getLocation()));
+ });
+ }
+
+ public void testConnectContentActivatorsWithFrameworkLoaders() {
+ doTestConnectContentActivators(false);
+ }
+
+ public void testConnectContentActivatorsWithProvidedLoaders() {
+ doTestConnectContentActivators(true);
+ }
+
+ void doTestConnectContentActivators(boolean provideLoader) {
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ final List<Integer> ids = Arrays.asList(1, 2, 3);
+ for (Integer id : ids) {
+ connector.setModule(id.toString(), createAdvancedModule(id, provideLoader));
+ }
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ for (Integer id : ids) {
+ Bundle b = f.getBundleContext().installBundle(id.toString());
+ assertEquals("Wrong symbolic name.", id.toString(), b.getSymbolicName());
+ b.start();
+ ServiceReference<?>[] registered = b.getRegisteredServices();
+ assertNotNull("No services found.", registered);
+ assertEquals("Wrong number of services.", 1, registered.length);
+ assertEquals("Wrong service property.", Activator.class.getSimpleName() + id,
+ (String) registered[0].getProperty("activator"));
+ if (provideLoader) {
+ assertTrue("Expected the same classes.",
+ Activator.class.equals(b.loadClass(Activator.class.getName())));
+ } else {
+ assertFalse("Expected different classes.",
+ Activator.class.equals(b.loadClass(Activator.class.getName())));
+ }
+ }
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ public void testConnectContentEntriesWithFrameworkLoaders() {
+ doTestConnectContentEntries(false);
+ }
+
+ public void testConnectContentEntriesWithProvidedLoaders() {
+ doTestConnectContentEntries(true);
+ }
+
+ void doTestConnectContentEntries(boolean provideLoader) {
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ final List<Integer> ids = Arrays.asList(1, 2, 3);
+ final Map<Integer, TestConnectModule> modules = new HashMap<>();
+ for (Integer id : ids) {
+ TestConnectModule m = createAdvancedModule(id, provideLoader);
+ modules.put(id, m);
+ connector.setModule(id.toString(), m);
+ }
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ for (Integer id : ids) {
+ Bundle b = f.getBundleContext().installBundle(id.toString());
+ assertEquals("Wrong symbolic name.", id.toString(), b.getSymbolicName());
+ TestConnectModule m = modules.get(id);
+ List<String> entries = new ArrayList<>();
+ for (String entry : m.getContent().getEntries()) {
+ entries.add(entry);
+ }
+
+ Set<String> bundleEntryUrls = new HashSet<>();
+ for (Enumeration<URL> eUrls = b.findEntries("/", "*", true); eUrls.hasMoreElements();) {
+ // URL paths always begin with '/', remove it
+ bundleEntryUrls.add(eUrls.nextElement().getPath().substring(1));
+ }
+ assertEquals("Wrong number of bundle entry URLs.", entries.size(), bundleEntryUrls.size());
+ assertTrue("Wrong bundle entry URLs: " + bundleEntryUrls, entries.containsAll(bundleEntryUrls));
+
+ List<String> bundleEntryPaths = new ArrayList<>();
+ for (Enumeration<String> ePaths = b
+ .getEntryPaths("org/eclipse/osgi/tests/bundles/resources"); ePaths.hasMoreElements();) {
+ bundleEntryPaths.add(ePaths.nextElement());
+ }
+ assertEquals("Wrong number of bundle entry paths from root.", 1, bundleEntryPaths.size());
+ assertEquals("Wrong bundle entry found at root.",
+ "org/eclipse/osgi/tests/bundles/resources/" + id + ".txt", bundleEntryPaths.get(0));
+
+ BundleWiring wiring = b.adapt(BundleWiring.class);
+ assertNotNull("No wiring.", wiring);
+ Collection<String> wiringResourcePaths = wiring.listResources("/", "*",
+ BundleWiring.LISTRESOURCES_LOCAL | BundleWiring.LISTRESOURCES_RECURSE);
+ assertEquals("Wrong number of resource paths.", entries.size(), wiringResourcePaths.size());
+ assertTrue("Wrong resource paths: " + wiringResourcePaths,
+ entries.containsAll(wiringResourcePaths));
+
+ Set<String> wiringEntryUrls = new HashSet<>();
+ for (URL url : wiring.findEntries("/", "*", BundleWiring.FINDENTRIES_RECURSE)) {
+ // URL paths always begin with '/', remove it
+ wiringEntryUrls.add(url.getPath().substring(1));
+ }
+ assertEquals("Wrong number of wiring entry URLs.", entries.size(), wiringEntryUrls.size());
+ assertTrue("Wrong wiring entry URLs: " + wiringEntryUrls, entries.containsAll(wiringEntryUrls));
+
+ String txtPathDir = "org/eclipse/osgi/tests/bundles/resources/";
+ String txtPath = txtPathDir + id + ".txt";
+ Optional<ConnectEntry> txtConnectEntry = m.getContent().getEntry(txtPath);
+ assertTrue("Could not find text entry.", txtConnectEntry.isPresent());
+
+ checkEntry(txtConnectEntry.get(), b.getEntry(txtPath), id);
+ checkEntry(txtConnectEntry.get(), b.getResource(txtPath), id);
+ Enumeration<URL> found = b.findEntries(txtPathDir, "*.txt", false);
+ checkEntry(txtConnectEntry.get(), found.nextElement(), id);
+ assertFalse("More entries found.", found.hasMoreElements());
+
+ // now try with leading '/'
+ String slashTxtPath = '/' + txtPath;
+ checkEntry(txtConnectEntry.get(), b.getEntry(slashTxtPath), id);
+ checkEntry(txtConnectEntry.get(), b.getResource(slashTxtPath), id);
+ found = b.findEntries('/' + txtPathDir, "*.txt", false);
+ checkEntry(txtConnectEntry.get(), found.nextElement(), id);
+ assertFalse("More entries found.", found.hasMoreElements());
+ }
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ public void testOpenCloseUpdateConnectContent() {
+ final String NAME1 = "testUpdate.1";
+ final String NAME2 = "testUpdate.2";
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ TestConnectModule m = createSimpleHeadersModule(NAME1);
+ connector.setModule(NAME1, m);
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ Bundle b = f.getBundleContext().installBundle(NAME1);
+ assertEquals("Wrong name.", NAME1, b.getSymbolicName());
+ // make sure to open the bundle file
+ assertNull(b.getEntry("doesNotExist.txt"));
+ TestConnectContent original = m.getContent();
+ assertTrue("Original content is not open.", original.isOpen());
+
+ // set the new content but don't update
+ m.setContent(createSimpleHeadersContent(NAME2));
+
+ FrameworkWiring fwkWiring = f.adapt(FrameworkWiring.class);
+ CountDownLatch refreshDone = new CountDownLatch(1);
+ fwkWiring.refreshBundles(Collections.singletonList(b), (e) -> refreshDone.countDown());
+ refreshDone.await();
+
+ // should still be NAME1
+ assertEquals("Wrong name.", NAME1, b.getSymbolicName());
+ assertTrue("Original content is not open.", original.isOpen());
+
+ // now update should stage in the new content
+ b.update();
+ assertEquals("Wrong name.", NAME2, b.getSymbolicName());
+ // make sure to open the bundle file
+ assertNull(b.getEntry("doesNotExist.txt"));
+ TestConnectContent newContent = m.getContent();
+ assertTrue("New content is not open.", newContent.isOpen());
+ assertFalse("Original content is open.", original.isOpen());
+
+ // now update with no new content
+ b.update();
+ assertNull(b.getEntry("doesNotExist.txt"));
+ assertTrue("New content is not open.", newContent.isOpen());
+ assertFalse("Original content is open.", original.isOpen());
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ }
+
+ public void testConnectBundleHeaders() throws IOException {
+ doTestConnectBundleHeaders(false, false);
+ doTestConnectBundleHeaders(true, false);
+ doTestConnectBundleHeaders(false, true);
+ doTestConnectBundleHeaders(true, true);
+ }
+
+ void doTestConnectBundleHeaders(boolean withSignedHook, boolean withManifest) throws IOException {
+ final String NAME1 = "bundle1";
+ final String NAME2 = "bundle2";
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ TestConnectModule m = withManifest ? createSimpleManifestModule(NAME1) : createSimpleHeadersModule(NAME1);
+ connector.setModule(NAME1, m);
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ Bundle b = f.getBundleContext().installBundle(NAME1);
+ Dictionary<String, String> headers1 = b.getHeaders();
+ assertEquals("Wrong name.", NAME1, b.getSymbolicName());
+ if (withManifest) {
+ assertEquals("Wrong symbolic name header.", NAME1, headers1.get(Constants.BUNDLE_SYMBOLICNAME));
+ } else {
+ checkHeaders(m.getContent().getHeaders().get(), headers1);
+ }
+ // set the new content
+ m.setContent(withManifest ? createSimpleManifestContent(NAME2) : createSimpleHeadersContent(NAME2));
+ b.update();
+ Dictionary<String, String> headers2 = b.getHeaders();
+ assertNotEquals("Headers not updated", headers1, headers2);
+ assertEquals("Wrong name.", NAME2, b.getSymbolicName());
+ if (withManifest) {
+ assertEquals("Wrong symbolic name header.", NAME2, headers2.get(Constants.BUNDLE_SYMBOLICNAME));
+ } else {
+ checkHeaders(m.getContent().getHeaders().get(), headers2);
+ }
+ b.uninstall();
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ }, withSignedHook);
+ }
+
+ public void testGetConnectHeaders() throws Exception {
+ final String NAME = "bundle";
+ final AtomicReference<Dictionary<String, String>> headers1 = new AtomicReference<>();
+ final AtomicReference<Dictionary<String, String>> headers2 = new AtomicReference<>();
+
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ TestConnectModule m = createSimpleHeadersModule(NAME);
+ connector.setModule(NAME, m);
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ Bundle b = f.getBundleContext().installBundle(NAME);
+ assertEquals("Wrong name.", NAME, b.getSymbolicName());
+ headers1.set(b.getHeaders());
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+
+ doTestConnect(connector, Collections.singletonMap(HookRegistry.PROP_HOOK_CONFIGURATORS_EXCLUDE,
+ "org.eclipse.equinox.weaving.hooks.WeavingHook"), (f) -> {
+ try {
+ f.start();
+ Bundle b = f.getBundleContext().getBundle(NAME);
+ assertFalse("Content is not closed", m.getContent().isOpen());
+ // Bundle.getHeaders() will eventually call
+ // ConnectBundleFile.getConnectHeaders() which opens the connect content
+ headers2.set(b.getHeaders());
+ assertTrue("Content is not open", m.getContent().isOpen());
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ });
+ Dictionary<String, String> h1 = headers1.get();
+ Dictionary<String, String> h2 = headers2.get();
+
+ assertEquals("Headers size not equal", h1.size(), h2.size());
+
+ for (Enumeration<String> keys = h1.keys(); keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ assertEquals(key + " header value not equal", h1.get(key), h2.get(key));
+ }
+ }
+
+ public void testInstallUpdateWithInputStream() throws Exception {
+ dotestInstallUpdate(false, false);
+ dotestInstallUpdate(false, true);
+ dotestInstallUpdate(true, false);
+ dotestInstallUpdate(true, true);
+ }
+
+ void dotestInstallUpdate(boolean installWithInputStream, boolean updateWithInputStream) throws Exception {
+ final InputStream in1 = installWithInputStream ? new URL(installer.getBundleLocation("test")).openStream()
+ : null;
+ final InputStream in2 = updateWithInputStream ? new URL(installer.getBundleLocation("test2")).openStream()
+ : null;
+ final String NAME1 = installWithInputStream ? "test1" : "bundle1";
+ final String NAME2 = updateWithInputStream ? "test2" : "bundle2";
+
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+
+ TestConnectModule m = createSimpleHeadersModule(NAME1);
+ connector.setModule(NAME1, m);
+
+ doTestConnect(connector, Collections.emptyMap(), (f) -> {
+ try {
+ f.start();
+ Bundle test = f.getBundleContext().installBundle(NAME1, in1);
+ assertEquals("Wrong name.", NAME1, test.getSymbolicName());
+ if (installWithInputStream) {
+ assertNotNull("Resource not found", test.getResource("stuff/data/resource1"));
+ }
+ m.setContent(createSimpleHeadersContent(NAME2));
+ test.update(in2);
+ assertEquals("Wrong name.", NAME2, test.getSymbolicName());
+ if (updateWithInputStream) {
+ assertNotNull("Resource not found", test.getResource("stuff/data/resource2"));
+ }
+ f.stop();
+ f.waitForStop(5000);
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ } finally {
+ cleanStorage();
+ }
+ });
+ }
+
+ public void testSystemBundleContent() {
+ TestCountingModuleConnector connector = new TestCountingModuleConnector();
+ Bundle systemBundle = getContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
+ Map<String, String> headers = new HashMap<>(FrameworkUtil.asMap(systemBundle.getHeaders()));
+ headers.put("test.key", "test.value");
+ // remove bundle manifest version to allow java export
+ headers.remove(Constants.BUNDLE_MANIFESTVERSION);
+
+ TestConnectModule systemModule = new TestConnectModule(
+ new TestConnectContent(headers, systemBundle.adapt(BundleWiring.class).getClassLoader()));
+ connector.setModule(Constants.SYSTEM_BUNDLE_LOCATION, systemModule);
+ Consumer<Framework> test = f -> {
+ try {
+ f.init();
+ Dictionary<String, String> h = f.getHeaders();
+ assertEquals("Wrong system BSN", systemBundle.getSymbolicName(), f.getSymbolicName());
+ assertEquals("Wrong test value", "test.value", h.get("test.key"));
+ } catch (Throwable t) {
+ sneakyThrow(t);
+ }
+ };
+
+ // run twice to test clean and persistent start
+ doTestConnect(connector, Collections.emptyMap(), test);
+ doTestConnect(connector, Collections.emptyMap(), test);
+ }
+
+ private void checkHeaders(Map<String, String> expected, Dictionary<String, String> actual) {
+ assertEquals("Headers size not equals", expected.size(), actual.size());
+ for (Entry<String, String> entry : expected.entrySet()) {
+ String key = entry.getKey();
+ assertEquals(key + " header value not equal", entry.getValue(), actual.get(key));
+ }
+ }
+
+ void checkEntry(ConnectEntry expected, URL actual, Integer id) throws IOException {
+ assertNotNull("No entry found.", actual);
+ assertEquals("Wrong path.", expected.getName(), actual.getPath().substring(1));
+ URLConnection connection = actual.openConnection();
+ assertEquals("Wrong last modified.", expected.getLastModified(), connection.getLastModified());
+ assertEquals("Wrong content length.", expected.getContentLength(), connection.getContentLengthLong());
+ byte[] expectedBytes = getBytes(expected.getInputStream());
+ byte[] actualBytes = getBytes(connection.getInputStream());
+ assertEquals("Wrong input steam size.", expectedBytes.length, actualBytes.length);
+ for (int i = 0; i < expectedBytes.length; i++) {
+ assertEquals("Wrong byte at: " + i, expectedBytes[i], actualBytes[i]);
+ }
+ String actualString = new String(actualBytes);
+ assertEquals("Wrong entry string.", id.toString(), actualString);
+ }
+
+ TestConnectModule createSimpleHeadersModule(String name) {
+ return new TestConnectModule(createSimpleHeadersContent(name));
+ }
+
+ TestConnectContent createSimpleHeadersContent(String name) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, name);
+ headers.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ return new TestConnectContent(headers, null);
+ }
+
+ TestConnectModule createSimpleManifestModule(String name) throws IOException {
+ return new TestConnectModule(createSimpleManifestContent(name));
+ }
+
+ TestConnectContent createSimpleManifestContent(String name) throws IOException {
+ Manifest manifest = new Manifest();
+ Attributes headers = manifest.getMainAttributes();
+ headers.putValue("Manifest-Version", "1");
+ headers.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.putValue(Constants.BUNDLE_SYMBOLICNAME, name);
+ headers.putValue(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ ByteArrayOutputStream manifestBytes = new ByteArrayOutputStream();
+ manifest.write(manifestBytes);
+ TestConnectContent c = new TestConnectContent(null, null);
+ addEntry("META-INF/MANIFEST.MF", manifestBytes.toByteArray(), c);
+ return c;
+ }
+
+ TestConnectModule createAdvancedModule(Integer id, boolean provideLoader) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, id.toString());
+ headers.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
+ headers.put(Constants.BUNDLE_ACTIVATOR, Activator.class.getName() + id);
+ TestConnectContent c = new TestConnectContent(headers, provideLoader ? getClass().getClassLoader() : null);
+ addEntry("org/", c);
+ addEntry("org/eclipse/", c);
+ addEntry("org/eclipse/osgi/", c);
+ addEntry("org/eclipse/osgi/tests/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/Activator.class", c);
+ addEntry("org/eclipse/osgi/tests/bundles/classes/Activator" + id + ".class", c);
+ addEntry("org/eclipse/osgi/tests/bundles/resources/", c);
+ addEntry("org/eclipse/osgi/tests/bundles/resources/" + id + ".txt", c);
+ return new TestConnectModule(c);
+ }
+
+ void addEntry(String name, TestConnectContent content) {
+ content.addEntry(name, new TestConnectEntryURL(name, getClass().getResource("/" + name)));
+ }
+
+ void addEntry(String name, byte[] bytes, TestConnectContent content) {
+ content.addEntry(name, new TestConnectEntryBytes(name, bytes));
+ }
+
+ static byte[] getBytes(InputStream in) throws IOException {
+ byte[] classbytes;
+ int bytesread = 0;
+ int readcount;
+ try {
+ int length = 1024;
+ classbytes = new byte[length];
+ readloop: while (true) {
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ byte[] oldbytes = classbytes;
+ length += 1024;
+ classbytes = new byte[length];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+
+ if (classbytes.length > bytesread) {
+ byte[] oldbytes = classbytes;
+ classbytes = new byte[bytesread];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+ return classbytes;
+ }
+
+ public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
+ throw (E) e;
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
index 8fecc99..f431426 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
@@ -118,7 +118,7 @@
// will sometimes result in failure presumably due to a locked
// file.
stop(equinox);
- rm(bundleFile);
+ delete(bundleFile);
equinox = restart(equinox, configuration);
assertDiscarded(location, equinox);
} finally {
@@ -215,21 +215,4 @@
file = new File(file, BUNDLE_MANIFEST);
assertTrue("Could not set last modified: " + file, file.setLastModified(file.lastModified() + 1000));
}
-
- public static boolean rm(File file) {
- if (file.exists()) {
- if (file.isDirectory()) {
- String list[] = file.list();
- if (list != null) {
- int len = list.length;
- for (int i = 0; i < len; i++) {
- rm(new File(file, list[i]));
- }
- }
- }
-
- return file.delete();
- }
- return (true);
- }
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ExtensionBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ExtensionBundleTests.java
index b94c08d..fb29534 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ExtensionBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ExtensionBundleTests.java
@@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.osgi.tests.bundles;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -28,6 +30,8 @@
return new TestSuite(ExtensionBundleTests.class);
}
+ public static List<String> events = new ArrayList<>();
+
public void testFrameworkExtension01() throws Exception {
Bundle fwkext = installer.installBundle("ext.framework.a", false); //$NON-NLS-1$
Bundle importer = installer.installBundle("ext.framework.a.importer"); //$NON-NLS-1$
@@ -84,4 +88,28 @@
BundleWire eeWire = wiring.getRequiredWires(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE).get(0);
assertEquals("Wrong provider for osgi.ee: " + eeWire.getProvider().getBundle(), 0, eeWire.getProvider().getBundle().getBundleId());
}
+
+ public void testActivatorOrder() throws Exception {
+ Bundle b = installer.installBundle("ext.framework.a", false);
+ Bundle bImp = installer.installBundle("ext.framework.a.importer");
+ Bundle bReq = installer.installBundle("ext.framework.a.requires");
+ installer.resolveBundles(new Bundle[] {b, bImp, bReq});
+
+ try {
+ bImp.start();
+ bReq.start();
+ } finally {
+ installer.uninstallAllBundles();
+ }
+ List<String> expectedEvents = Arrays.asList(bImp.getSymbolicName() + " STARTED", bReq.getSymbolicName() + " STARTED", bReq.getSymbolicName() + " STOPPED", bImp.getSymbolicName() + " STOPPED");
+ assertEquals("Expected number of events not found", expectedEvents.size(), events.size());
+ for (int i = 0; i < events.size(); i++) {
+ assertEquals("Expected event not found", expectedEvents.get(i), events.get(i));
+ }
+ }
+
+ public void tearDown() throws Exception {
+ super.tearDown();
+ events.clear();
+ }
}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ImportJavaSEPackagesTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ImportJavaSEPackagesTests.java
index 2e4bb93..da55e92 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ImportJavaSEPackagesTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ImportJavaSEPackagesTests.java
@@ -109,7 +109,6 @@
public void testSystemPackages() throws Exception {
Map<Integer, Integer> packagesPerVersion = new HashMap<>();
- packagesPerVersion.put(7, 56);
packagesPerVersion.put(8, 63);
if (!originalSpecVersion.startsWith("1.")) {
packagesPerVersion.put(9, calculateJavaPackageCount());
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java
index b67f9f6..2c3c875 100755
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java
@@ -793,25 +793,25 @@
}
public void testChangeEE() throws IOException, BundleException {
- URL javaSE7Profile = OSGiTestsActivator.getContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).getEntry("JavaSE-1.7.profile");
URL javaSE8Profile = OSGiTestsActivator.getContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).getEntry("JavaSE-1.8.profile");
+ URL javaSE9Profile = OSGiTestsActivator.getContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).getEntry("JavaSE-9.profile");
- // configure equinox for javaSE 8
+ // configure equinox for javaSE 9
File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$
Map<String, Object> configuration = new HashMap<>();
configuration.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath());
- configuration.put("osgi.java.profile", javaSE8Profile.toExternalForm()); //$NON-NLS-1$
+ configuration.put("osgi.java.profile", javaSE9Profile.toExternalForm()); //$NON-NLS-1$
Equinox equinox = new Equinox(configuration);
equinox.start();
- // install a bundle that requires java 8
+ // install a bundle that requires java 9
BundleContext systemContext = equinox.getBundleContext();
assertNotNull("System context is null", systemContext); //$NON-NLS-1$
Map<String, String> testHeaders = new HashMap<>();
testHeaders.put(Constants.BUNDLE_MANIFESTVERSION, "2");
testHeaders.put(Constants.BUNDLE_SYMBOLICNAME, getName());
- testHeaders.put(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT, "JavaSE-1.8");
+ testHeaders.put(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT, "JavaSE-9");
File testBundle = createBundle(config, getName(), testHeaders);
Bundle b = systemContext.installBundle("reference:file:///" + testBundle.getAbsolutePath()); //$NON-NLS-1$
long bid = b.getBundleId();
@@ -822,8 +822,8 @@
// put the framework back to the RESOLVED state
stop(equinox);
- // configure equinox for java 7
- configuration.put("osgi.java.profile", javaSE7Profile.toExternalForm());
+ // configure equinox for java 8
+ configuration.put("osgi.java.profile", javaSE8Profile.toExternalForm());
equinox = new Equinox(configuration);
try {
equinox.start();
@@ -837,8 +837,8 @@
// put the framework back to the RESOLVED state
stop(equinox);
- // move back to java 8
- configuration.put("osgi.java.profile", javaSE8Profile.toExternalForm());
+ // move back to java 9
+ configuration.put("osgi.java.profile", javaSE9Profile.toExternalForm());
equinox = new Equinox(configuration);
try {
equinox.start();
@@ -2223,7 +2223,7 @@
config.mkdirs();
Map<String, Object> configuration = new HashMap<>();
configuration.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath());
- configuration.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, "osgi.ee; osgi.ee=JavaSE; version:Version=1.7, something.system");
+ configuration.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, "osgi.ee; osgi.ee=JavaSE; version:Version=1.8, something.system");
configuration.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "something.system");
configuration.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA, "something.extra");
configuration.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "something.extra");
@@ -2294,7 +2294,6 @@
doTestJavaProfile("1.10.1", "JavaSE-1.8", null);
doTestJavaProfile("1.9", "JavaSE-1.8", null);
doTestJavaProfile("1.8", "JavaSE-1.8", null);
- doTestJavaProfile("1.7", "JavaSE-1.7", null);
doTestJavaProfile("1.8", "JavaSE/compact3-1.8", "compact3");
doTestJavaProfile("1.8", "JavaSE/compact3-1.8", "\"compact3\"");
doTestJavaProfile("1.8", "JavaSE/compact3-1.8", " \"compact3\" ");
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java
new file mode 100644
index 0000000..1294453
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+import java.util.Collections;
+import java.util.Hashtable;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ context.registerService(Activator.class, this, new Hashtable<>(Collections.singletonMap("activator", this.getClass().getSimpleName())));
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ // do nothing
+ }
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java
new file mode 100644
index 0000000..527a559
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator1.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator1 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java
new file mode 100644
index 0000000..a223183
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator2.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator2 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java
new file mode 100644
index 0000000..272821d
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/classes/Activator3.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles.classes;
+
+public class Activator3 extends Activator {
+ // nothing
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt
new file mode 100644
index 0000000..56a6051
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/1.txt
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt
new file mode 100644
index 0000000..d8263ee
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/2.txt
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt
new file mode 100644
index 0000000..e440e5c
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/resources/3.txt
@@ -0,0 +1 @@
+3
\ No newline at end of file
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
index f9fbd40..8985c5c 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
@@ -483,5 +483,10 @@
}
return new CaseInsensitiveDictionaryMap(dictionary);
}
+
+ @Override
+ public Object adapt(Class type) {
+ return null;
+ }
}
}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
index 50210a9..8dd1184 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java
@@ -30,6 +30,7 @@
import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.eclipse.osgi.tests.bundles.BundleInstaller;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.connect.FrameworkUtilHelper;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -73,7 +74,7 @@
throw new RuntimeException(e);
}
}
- if (name.startsWith("org.eclipse") || name.startsWith("org.osgi.framework.FrameworkUtil")) {
+ if (name.startsWith("org.eclipse") || name.startsWith("org.osgi.framework.FrameworkUtil") || name.equals(FrameworkUtilHelper.class.getName())) {
Class<?> result = findLoadedClass(name);
if (result == null)
result = findClass(name);
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ActivatorOrderTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ActivatorOrderTest.java
new file mode 100644
index 0000000..6d33025
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ActivatorOrderTest.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.hooks.framework;
+
+import static org.eclipse.osgi.tests.bundles.AbstractBundleTests.stop;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.eclipse.osgi.tests.OSGiTestsActivator;
+import org.osgi.framework.Constants;
+import org.osgi.framework.launch.Framework;
+
+public class ActivatorOrderTest extends AbstractFrameworkHookTests {
+
+ private Framework framework;
+ private static final String HOOK_CONFIGURATOR_BUNDLE = "activator.hooks.a";
+ private static final String HOOK_CONFIGURATOR_CLASS1 = "org.eclipse.osgi.tests.hooks.framework.activator.a.TestHookConfigurator1";
+ private static final String HOOK_CONFIGURATOR_CLASS2 = "org.eclipse.osgi.tests.hooks.framework.activator.a.TestHookConfigurator2";
+ private static final String HOOK_CONFIGURATOR_CLASS3 = "org.eclipse.osgi.tests.hooks.framework.activator.a.TestHookConfigurator3";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ String loc = bundleInstaller.getBundleLocation(HOOK_CONFIGURATOR_BUNDLE);
+ loc = loc.substring(loc.indexOf("file:"));
+ classLoader.addURL(new URL(loc));
+ File file = OSGiTestsActivator.getContext().getDataFile(getName());
+ HashMap<String, String> configuration = new HashMap<>();
+ configuration.put(Constants.FRAMEWORK_STORAGE, file.getAbsolutePath());
+ configuration.put(HookRegistry.PROP_HOOK_CONFIGURATORS, HOOK_CONFIGURATOR_CLASS1 + "," + HOOK_CONFIGURATOR_CLASS2 + "," + HOOK_CONFIGURATOR_CLASS3);
+
+ framework = createFramework(configuration);
+ }
+
+ public void testActivatorOrder() throws Exception {
+ List<String> actualEvents = new ArrayList<>();
+ Class<?> clazz1 = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS1);
+ clazz1.getField("events").set(null, actualEvents);
+ Class<?> clazz2 = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS2);
+ clazz2.getField("events").set(null, actualEvents);
+ Class<?> clazz3 = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS3);
+ clazz3.getField("events").set(null, actualEvents);
+
+ List<String> expectedEvents = Arrays.asList("HOOK1 STARTED", "HOOK2 STARTED", "HOOK3 STARTED", "HOOK3 STOPPED", "HOOK2 STOPPED", "HOOK1 STOPPED");
+
+ initAndStart(framework);
+ stop(framework);
+ assertEquals("Activator order not as expected", expectedEvents, actualEvents);
+
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java
index dc6c570..3e35b93 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java
@@ -25,6 +25,7 @@
suite.addTest(new TestSuite(ContextFinderTests.class));
suite.addTest(new TestSuite(DevClassPathWithExtensionTests.class));
suite.addTest(new TestSuite(EmbeddedEquinoxWithURLInClassLoadTests.class));
+ suite.addTest(new TestSuite(ActivatorOrderTest.class));
return suite;
}
}
diff --git a/bundles/org.eclipse.osgi/.classpath b/bundles/org.eclipse.osgi/.classpath
index 150b59d..d1e9a6c 100644
--- a/bundles/org.eclipse.osgi/.classpath
+++ b/bundles/org.eclipse.osgi/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="osgi/src">
<attributes>
diff --git a/bundles/org.eclipse.osgi/.settings/.api_filters b/bundles/org.eclipse.osgi/.settings/.api_filters
new file mode 100644
index 0000000..f1f547e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/.settings/.api_filters
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.osgi" version="2">
+ <resource path="osgi/src/org/osgi/framework/FrameworkUtil.java" type="org.osgi.framework.FrameworkUtil">
+ <filter comment="Not for OSGi API" id="1141899266">
+ <message_arguments>
+ <message_argument value="1.10"/>
+ <message_argument value="3.16"/>
+ <message_argument value="asDictionary(Map<? extends K,? extends V>)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi API" id="1141899266">
+ <message_arguments>
+ <message_argument value="1.10"/>
+ <message_argument value="3.16"/>
+ <message_argument value="asMap(Dictionary<? extends K,? extends V>)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi API" id="1141899266">
+ <message_arguments>
+ <message_argument value="1.10"/>
+ <message_argument value="3.16"/>
+ <message_argument value="getBundle(ClassLoader)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/ServiceReference.java" type="org.osgi.framework.ServiceReference">
+ <filter comment="Not for OSGi API" id="403804204">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.ServiceReference"/>
+ <message_argument value="adapt(Class<A>)"/>
+ </message_arguments>
+ </filter>
+ <filter id="403984517">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.ServiceReference"/>
+ <message_argument value="org.osgi.framework.BundleReference"/>
+ <message_argument value="getBundle()"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi API" id="1209008130">
+ <message_arguments>
+ <message_argument value="1.10"/>
+ <message_argument value="3.16"/>
+ <message_argument value="adapt(Class<A>)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectContent.java" type="org.osgi.framework.connect.ConnectContent">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectContent"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectFrameworkFactory.java" type="org.osgi.framework.connect.ConnectFrameworkFactory">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectFrameworkFactory"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ConnectModule.java" type="org.osgi.framework.connect.ConnectModule">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ConnectModule"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java" type="org.osgi.framework.connect.FrameworkUtilHelper">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.FrameworkUtilHelper"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/connect/ModuleConnector.java" type="org.osgi.framework.connect.ModuleConnector">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.connect.ModuleConnector"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/launch/FrameworkFactory.java" type="org.osgi.framework.launch.FrameworkFactory">
+ <filter comment="Not for OSGi packages" id="403804204">
+ <message_arguments>
+ <message_argument value="org.osgi.framework.launch.FrameworkFactory"/>
+ <message_argument value="newFramework(Map<String,String>, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi packages" id="1209008130">
+ <message_arguments>
+ <message_argument value="1.3"/>
+ <message_argument value="3.16"/>
+ <message_argument value="newFramework(Map<String,String>, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Not for OSGi packages" id="1211105284">
+ <message_arguments>
+ <message_argument value="newFramework(Map<String,String>, ConnectFactory)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/framework/namespace/IdentityNamespace.java" type="org.osgi.framework.namespace.IdentityNamespace">
+ <filter comment="Not for OSGi API" id="1141899266">
+ <message_arguments>
+ <message_argument value="1.2"/>
+ <message_argument value="3.16"/>
+ <message_argument value="CAPABILITY_TAGS_ATTRIBUTE"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="osgi/src/org/osgi/service/condition/Condition.java" type="org.osgi.service.condition.Condition">
+ <filter comment="Not for OSGi API" id="1110441988">
+ <message_arguments>
+ <message_argument value="org.osgi.service.condition.Condition"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/bundles/org.eclipse.osgi/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi/.settings/org.eclipse.jdt.core.prefs
index d14e296..11ab09e 100644
--- a/bundles/org.eclipse.osgi/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi/.settings/org.eclipse.jdt.core.prefs
@@ -13,9 +13,10 @@
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -31,6 +32,7 @@
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=error
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
@@ -69,7 +71,7 @@
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=warning
@@ -87,6 +89,7 @@
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
@@ -119,7 +122,8 @@
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
diff --git a/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs b/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
index 5b3c8e0..8dd4a28 100644
--- a/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
+++ b/bundles/org.eclipse.osgi/.settings/org.eclipse.pde.api.tools.prefs
@@ -1,11 +1,17 @@
-#Thu Oct 08 09:47:30 CDT 2009
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
@@ -45,6 +51,7 @@
ILLEGAL_INSTANTIATE=Warning
ILLEGAL_OVERRIDE=Warning
ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
@@ -56,6 +63,7 @@
INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
INVALID_JAVADOC_TAG=Ignore
INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
LEAK_EXTEND=Warning
@@ -73,6 +81,7 @@
METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Warning
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
@@ -80,10 +89,14 @@
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
eclipse.preferences.version=1
incompatible_api_component_version=Error
incompatible_api_component_version_include_major_without_breaking_change=Disabled
incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Warning
invalid_since_tag_version=Error
malformed_since_tag=Error
missing_since_tag=Error
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index bed5f7f..eb97f5f 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -6,6 +6,7 @@
org.eclipse.osgi.container;version="1.5";
uses:="org.eclipse.osgi.report.resolution,
org.osgi.framework.wiring,
+ org.eclipse.osgi.framework.eventmgr,
org.osgi.framework.startlevel,
org.osgi.framework,
org.osgi.framework.hooks.resolver,
@@ -34,7 +35,7 @@
org.eclipse.osgi.internal.serviceregistry;x-internal:=true,
org.eclipse.osgi.internal.signedcontent;x-internal:=true,
org.eclipse.osgi.internal.url;x-internal:=true,
- org.eclipse.osgi.launch;version="1.0";uses:="org.osgi.framework,org.osgi.framework.launch",
+ org.eclipse.osgi.launch;version="1.1";uses:="org.osgi.framework,org.osgi.framework.launch,org.osgi.framework.connect",
org.eclipse.osgi.report.resolution;version="1.0";uses:="org.osgi.service.resolver,org.osgi.resource",
org.eclipse.osgi.service.datalocation;version="1.3",
org.eclipse.osgi.service.debug;version="1.2",
@@ -52,22 +53,24 @@
org.eclipse.osgi.storagemanager;version="1.0",
org.eclipse.osgi.util;version="1.1",
org.osgi.dto;version="1.1",
- org.osgi.framework;version="1.9",
+ org.osgi.framework;version="1.10",
+ org.osgi.framework.connect;version="1.0";uses:="org.osgi.framework.launch",
org.osgi.framework.dto;version="1.8";uses:="org.osgi.dto",
org.osgi.framework.hooks.bundle;version="1.1";uses:="org.osgi.framework",
org.osgi.framework.hooks.resolver;version="1.0";uses:="org.osgi.framework.wiring",
org.osgi.framework.hooks.service;version="1.1";uses:="org.osgi.framework",
org.osgi.framework.hooks.weaving;version="1.1";uses:="org.osgi.framework.wiring",
org.osgi.framework.launch;version="1.2";uses:="org.osgi.framework",
- org.osgi.framework.namespace;version="1.1";uses:="org.osgi.resource",
+ org.osgi.framework.namespace;version="1.2";uses:="org.osgi.resource",
org.osgi.framework.startlevel;version="1.0";uses:="org.osgi.framework",
org.osgi.framework.startlevel.dto;version="1.0";uses:="org.osgi.dto",
org.osgi.framework.wiring;version="1.2";uses:="org.osgi.framework,org.osgi.resource",
org.osgi.framework.wiring.dto;version="1.3";uses:="org.osgi.dto,org.osgi.resource.dto",
org.osgi.resource;version="1.0",
org.osgi.resource.dto;version="1.0";uses:="org.osgi.dto",
+ org.osgi.service.condition;version="1.0",
org.osgi.service.condpermadmin;version="1.1.1";uses:="org.osgi.framework",
- org.osgi.service.log;version="1.4";uses:="org.osgi.framework",
+ org.osgi.service.log;version="1.5";uses:="org.osgi.framework",
org.osgi.service.log.admin;version="1.0";uses:="org.osgi.service.log",
org.osgi.service.packageadmin;version="1.2";uses:="org.osgi.framework",
org.osgi.service.permissionadmin;version="1.2",
@@ -101,12 +104,12 @@
Bundle-Description: %systemBundle
Bundle-Copyright: %copyright
Bundle-Vendor: %eclipse.org
-Bundle-Version: 3.15.300.qualifier
+Bundle-Version: 3.16.0.qualifier
Bundle-Localization: systembundle
Bundle-DocUrl: http://www.eclipse.org
Eclipse-ExtensibleAPI: true
Eclipse-SystemBundle: true
Main-Class: org.eclipse.core.runtime.adaptor.EclipseStarter
-Require-Capability: osgi.ee; filter:="(| (&(osgi.ee=JavaSE)(version=1.7)) (&(osgi.ee=JavaSE/compact1)(version=1.8)) )"
+Require-Capability: osgi.ee; filter:="(| (&(osgi.ee=JavaSE)(version=1.8)) (&(osgi.ee=JavaSE/compact1)(version=1.8)) )"
Eclipse-BundleShape: jar
Automatic-Module-Name: org.eclipse.osgi
diff --git a/bundles/org.eclipse.osgi/META-INF/native-image/native-image.properties b/bundles/org.eclipse.osgi/META-INF/native-image/native-image.properties
new file mode 100644
index 0000000..301a266
--- /dev/null
+++ b/bundles/org.eclipse.osgi/META-INF/native-image/native-image.properties
@@ -0,0 +1,30 @@
+Args = --initialize-at-build-time=\
+org.apache.felix.resolver,\
+org.eclipse.equinox.log,\
+org.eclipse.osgi,\
+org.osgi.dto,\
+org.osgi.framework,\
+org.osgi.framework.connect,\
+org.osgi.framework.dto,\
+org.osgi.framework.hooks.bundle,\
+org.osgi.framework.hooks.resolver,\
+org.osgi.framework.hooks.service,\
+org.osgi.framework.hooks.weaving,\
+org.osgi.framework.launch,\
+org.osgi.framework.namespace,\
+org.osgi.framework.startlevel,\
+org.osgi.framework.startlevel.dto,\
+org.osgi.framework.wiring,\
+org.osgi.framework.wiring.dto,\
+org.osgi.resource,\
+org.osgi.resource.dto,\
+org.osgi.service.condpermadmin,\
+org.osgi.service.cm,\
+org.osgi.service.log,\
+org.osgi.service.log.admin,\
+org.osgi.service.packageadmin,\
+org.osgi.service.permissionadmin,\
+org.osgi.service.resolver,\
+org.osgi.service.startlevel,\
+org.osgi.service.url,\
+org.osgi.util.tracker
diff --git a/bundles/org.eclipse.osgi/META-INF/native-image/proxy-config.json b/bundles/org.eclipse.osgi/META-INF/native-image/proxy-config.json
new file mode 100644
index 0000000..50a895a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/META-INF/native-image/proxy-config.json
@@ -0,0 +1,3 @@
+[
+ ["org.osgi.service.cm.SynchronousConfigurationListener"]
+]
diff --git a/bundles/org.eclipse.osgi/META-INF/native-image/reflect-config.json b/bundles/org.eclipse.osgi/META-INF/native-image/reflect-config.json
new file mode 100644
index 0000000..12dfa3e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/META-INF/native-image/reflect-config.json
@@ -0,0 +1,109 @@
+[
+{
+ "name":"org.osgi.service.cm.SynchronousConfigurationListener",
+ "allDeclaredMethods":true,
+ "allPublicConstructors":true
+},
+{
+ "name":"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl",
+ "allPublicConstructors":true
+},
+{
+ "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl",
+ "allPublicConstructors":true
+},
+{
+ "name":"com.sun.xml.internal.stream.XMLInputFactoryImpl",
+ "allPublicConstructors":true
+},
+{
+ "name":"java.lang.Boolean",
+ "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
+},
+{
+ "name":"java.lang.Object",
+ "allDeclaredMethods":true
+},
+{
+ "name":"java.lang.System",
+ "allPublicMethods":true
+},
+{
+ "name":"java.net.URL",
+ "allDeclaredFields":true
+},
+{
+ "name":"java.net.URLClassLoader",
+ "methods":[{"name":"addURL","parameterTypes":["java.net.URL"] }]
+},
+{
+ "name":"java.net.URLConnection",
+ "allDeclaredFields":true
+},
+{
+ "name":"java.util.HashSet",
+ "methods":[{"name":"clone","parameterTypes":[] }]
+},
+{
+ "name":"javax.xml.parsers.SAXParserFactory"
+},
+{
+ "name":"org.eclipse.osgi.container.ModuleWiring",
+ "fields":[{"name":"dynamicMissRef"}]
+},
+{
+ "name":"org.eclipse.osgi.internal.cds.CDSHookConfigurator",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.eclipse.osgi.internal.connect.ConnectHookConfigurator",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.eclipse.osgi.internal.framework.BundleContextImpl",
+ "allPublicMethods":true
+},
+{
+ "name":"org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle",
+ "allPublicMethods":true
+},
+{
+ "name":"org.eclipse.osgi.internal.framework.SystemBundleActivator",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.eclipse.osgi.internal.signedcontent.SignedBundleHook",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.eclipse.osgi.launch.EquinoxFactory",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.eclipse.osgi.service.resolver.BundleDescription"
+},
+{
+ "name":"org.osgi.service.cm.Configuration",
+ "methods":[
+ {"name":"getFactoryPid","parameterTypes":[] },
+ {"name":"getPid","parameterTypes":[] },
+ {"name":"getProperties","parameterTypes":[] }
+ ]
+},
+{
+ "name":"org.osgi.service.cm.ConfigurationAdmin",
+ "methods":[
+ {"name":"getConfiguration","parameterTypes":["java.lang.String","java.lang.String"] },
+ {"name":"listConfigurations","parameterTypes":["java.lang.String"] }
+ ]
+},
+{
+ "name":"org.osgi.service.cm.ConfigurationEvent",
+ "methods":[
+ {"name":"getFactoryPid","parameterTypes":[] },
+ {"name":"getPid","parameterTypes":[] },
+ {"name":"getReference","parameterTypes":[] },
+ {"name":"getType","parameterTypes":[] }
+ ]
+}
+]
diff --git a/bundles/org.eclipse.osgi/META-INF/native-image/resource-config.json b/bundles/org.eclipse.osgi/META-INF/native-image/resource-config.json
new file mode 100644
index 0000000..dc878ee
--- /dev/null
+++ b/bundles/org.eclipse.osgi/META-INF/native-image/resource-config.json
@@ -0,0 +1,14 @@
+{
+ "resources":[
+ {"pattern":"META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory"},
+ {"pattern":"META-INF/services/org.osgi.framework.connect.FrameworkUtilHelper"},
+ {"pattern":"META-INF/services/org.osgi.framework.launch.FrameworkFactory"},
+ {"pattern":"hookconfigurators.properties"},
+ {"pattern":"org/eclipse/osgi/internal/framework/osname.aliases"},
+ {"pattern":"org/eclipse/osgi/internal/framework/processor.aliases"},
+ {"pattern":"org/eclipse/osgi/internal/messages/ExternalMessages.properties"},
+ {"pattern":"org/eclipse/osgi/internal/permadmin/implied.permissions"},
+ {"pattern":"org/eclipse/osgi/internal/signedcontent/SignedContentMessages.properties"},
+ {"pattern":"org/eclipse/osgi/internal/url/SetAccessible.bytes"}
+ ]
+}
diff --git a/bundles/org.eclipse.osgi/META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory b/bundles/org.eclipse.osgi/META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
new file mode 100644
index 0000000..6cd04c1
--- /dev/null
+++ b/bundles/org.eclipse.osgi/META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
@@ -0,0 +1 @@
+org.eclipse.osgi.launch.EquinoxFactory
diff --git a/bundles/org.eclipse.osgi/build.properties b/bundles/org.eclipse.osgi/build.properties
index 70f107d..e6ec93e 100644
--- a/bundles/org.eclipse.osgi/build.properties
+++ b/bundles/org.eclipse.osgi/build.properties
@@ -38,4 +38,4 @@
jars.extra.classpath = osgi/osgi.annotation.jar,\
osgi/function.interface.jar,\
osgi/j9stubs.jar
-jre.compilation.profile = JavaSE-1.7
+jre.compilation.profile = JavaSE-1.8
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
index 5eddeaf..dfdc819 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
@@ -37,6 +37,7 @@
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.internal.loader.classpath.FragmentClasspath;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
@@ -192,6 +193,9 @@
//////////////// BundleFileWrapperFactoryHook //////////////
@Override
public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
+ if (generation.getContentType() == Type.CONNECT) {
+ return null;
+ }
// wrap the real bundle file for purposes of loading shared classes.
CDSBundleFile newBundleFile;
if (!base && generation.getBundleInfo().getBundleId() != 0) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java
new file mode 100644
index 0000000..2570312
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFile.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import org.eclipse.osgi.internal.debug.Debug;
+import org.eclipse.osgi.storage.BundleInfo;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.CloseableBundleFile;
+import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectContent.ConnectEntry;
+import org.osgi.framework.connect.ConnectModule;
+
+public class ConnectBundleFile extends CloseableBundleFile<ConnectEntry> {
+ public class ConnectBundleEntry extends BundleEntry {
+ private final ConnectEntry connectEntry;
+
+ public ConnectBundleEntry(ConnectEntry entry) {
+ this.connectEntry = entry;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return ConnectBundleFile.this.getInputStream(connectEntry);
+ }
+
+ @Override
+ public byte[] getBytes() throws IOException {
+ return connectEntry.getBytes();
+ }
+
+ @Override
+ public long getSize() {
+ return connectEntry.getContentLength();
+ }
+
+ @Override
+ public String getName() {
+ return connectEntry.getName();
+ }
+
+ @Override
+ public long getTime() {
+ return connectEntry.getLastModified();
+ }
+
+ @Override
+ public URL getFileURL() {
+ File file = ConnectBundleFile.this.getFile(getName(), false);
+ if (file != null) {
+ try {
+ return file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // should never happen
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public URL getLocalURL() {
+ // TODO Not sure what to do here
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final ConnectContent content;
+
+ public ConnectBundleFile(ConnectModule module, File basefile, BundleInfo.Generation generation, MRUBundleFileList mruList, Debug debug) throws IOException {
+ super(basefile, generation, mruList, debug);
+ this.content = module.getContent();
+ }
+
+ @Override
+ protected void doOpen() throws IOException {
+ content.open();
+ }
+
+ @Override
+ protected Iterable<String> getPaths() {
+ try {
+ return content.getEntries();
+ } catch (IOException e) {
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ protected BundleEntry findEntry(String path) {
+ if (path.length() > 0 && path.charAt(0) == '/') {
+ path = path.substring(1);
+ }
+ return content.getEntry(path).map(ConnectBundleEntry::new).orElse(null);
+ }
+
+ @Override
+ protected void doClose() throws IOException {
+ content.close();
+ }
+
+ @Override
+ protected void postClose() {
+ // do nothing
+ }
+
+ @Override
+ protected InputStream doGetInputStream(ConnectEntry entry) throws IOException {
+ return entry.getInputStream();
+ }
+
+ public Map<String, String> getConnectHeaders() {
+ if (!lockOpen()) {
+ return null;
+ }
+ try {
+ return content.getHeaders().orElse(null);
+ } finally {
+ releaseOpen();
+ }
+ }
+
+ Optional<ClassLoader> getClassLoader() {
+ return content.getClassLoader();
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
new file mode 100644
index 0000000..a7e764c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import static org.eclipse.osgi.internal.framework.EquinoxContainer.sneakyThrow;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.osgi.container.Module;
+import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
+import org.eclipse.osgi.container.ModuleRevisionBuilder;
+import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
+import org.eclipse.osgi.internal.framework.EquinoxContainer.ConnectModules;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
+import org.eclipse.osgi.internal.hookregistry.StorageHookFactory;
+import org.eclipse.osgi.internal.hookregistry.StorageHookFactory.StorageHook;
+import org.eclipse.osgi.internal.loader.BundleLoader;
+import org.eclipse.osgi.internal.loader.ModuleClassLoader;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectModule;
+import org.osgi.framework.connect.ModuleConnector;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+
+public class ConnectHookConfigurator implements HookConfigurator {
+ static final Collection<String> CONNECT_TAG_NAMESPACES = new ArrayList<>(Arrays.asList(
+ BundleNamespace.BUNDLE_NAMESPACE, HostNamespace.HOST_NAMESPACE, IdentityNamespace.IDENTITY_NAMESPACE));
+
+ @Override
+ public void addHooks(final HookRegistry hookRegistry) {
+ final ConnectModules connectModules = hookRegistry.getContainer().getConnectModules();
+ ModuleConnector moduleConnector = connectModules.getModuleConnector();
+
+ hookRegistry.addStorageHookFactory(new StorageHookFactory<Object, Object, StorageHook<Object, Object>>() {
+ @Override
+ protected StorageHook<Object, Object> createStorageHook(Generation generation) {
+ final ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
+
+ return new StorageHook<Object, Object>(generation, this.getClass()) {
+ boolean hasModule = false;
+
+ @Override
+ public void save(Object saveContext, DataOutputStream os) throws IOException {
+ os.writeBoolean(m != null);
+ }
+
+ @Override
+ public void load(Object loadContext, DataInputStream is) throws IOException {
+ hasModule = is.readBoolean();
+ }
+
+ @Override
+ public void validate() throws IllegalStateException {
+ // make sure we have the module still from the factory
+ if (hasModule && m == null) {
+ throw new IllegalStateException("Connect Factory no longer has the module at locataion: " + generation.getBundleInfo().getLocation()); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public ModuleRevisionBuilder adaptModuleRevisionBuilder(ModuleEvent operation, Module origin, ModuleRevisionBuilder builder) {
+ if (m != null) {
+ builder.getCapabilities()
+ .stream() //
+ .filter(c -> CONNECT_TAG_NAMESPACES.contains(c.getNamespace())) //
+ .forEach((c) -> {
+ c.getAttributes().compute(IdentityNamespace.CAPABILITY_TAGS_ATTRIBUTE, (k, v) -> {
+ if (v == null) {
+ return Collections.singletonList(ConnectContent.TAG_OSGI_CONNECT);
+ }
+ if (v instanceof List) {
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ List<String> l = new ArrayList<>((List) v);
+ l.add(ConnectContent.TAG_OSGI_CONNECT);
+ return Collections.unmodifiableList(l);
+ }
+ // should not get here, but just recover
+ return Arrays.asList(v, ConnectContent.TAG_OSGI_CONNECT);
+ });
+ });
+ return builder;
+ }
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public URLConnection handleContentConnection(Module module, String location, InputStream in) {
+ if (in != null) {
+ // Do not call ModuleConnector method connect when input stream is non null.
+ return null;
+ }
+ if (location == null) {
+ location = module.getLocation();
+ }
+ try {
+ ConnectModule m = connectModules.connect(location);
+ if (m != null) {
+ return ConnectInputStream.URL_CONNECTION_INSTANCE;
+ }
+ } catch (IllegalStateException e) {
+ if (e.getCause() instanceof BundleException) {
+ sneakyThrow(e.getCause());
+ }
+ }
+ return null;
+ }
+ });
+
+ if (moduleConnector == null) {
+ return;
+ }
+
+ hookRegistry.addClassLoaderHook(new ClassLoaderHook() {
+ @Override
+ public ModuleClassLoader createClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, Generation generation) {
+ ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
+ if (m != null) {
+ BundleFile bundlefile = generation.getBundleFile();
+ if (bundlefile instanceof BundleFileWrapperChain) {
+ BundleFileWrapperChain chain = (BundleFileWrapperChain) bundlefile;
+ while (chain.getNext() != null) {
+ chain = chain.getNext();
+ }
+ bundlefile = chain.getBundleFile();
+ }
+ if (bundlefile instanceof ConnectBundleFile) {
+ return ((ConnectBundleFile) bundlefile).getClassLoader().map((l) //
+ -> new DelegatingConnectClassLoader(parent, configuration, delegate, generation, l)).orElse(null);
+ }
+ }
+ return null;
+ }
+ });
+
+ hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
+
+ @Override
+ public BundleActivator createActivator() {
+ final List<BundleActivator> activators = new ArrayList<>();
+ moduleConnector.newBundleActivator().ifPresent((a) -> activators.add(a));
+ return new BundleActivator() {
+ @Override
+ public void start(BundleContext context) throws Exception {
+ for (BundleActivator activator : activators) {
+ activator.start(context);
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ for (BundleActivator activator : activators) {
+ activator.stop(context);
+ }
+ }
+ };
+ }
+ });
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java
new file mode 100644
index 0000000..1d5ed69
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import org.eclipse.osgi.storage.ContentProvider;
+
+public class ConnectInputStream extends InputStream implements ContentProvider {
+ static final ConnectInputStream INSTANCE = new ConnectInputStream();
+ static final URLConnection URL_CONNECTION_INSTANCE = new URLConnection(null) {
+ @Override
+ public void connect() throws IOException {
+ connected = true;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return INSTANCE;
+ }
+ };
+
+ private ConnectInputStream() {
+ }
+
+ /* This method should not be called.
+ */
+ @Override
+ public int read() throws IOException {
+ throw new IOException();
+ }
+
+ public File getContent() {
+ return null;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.CONNECT;
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java
new file mode 100644
index 0000000..d9e1cf5
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/DelegatingConnectClassLoader.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
+import org.eclipse.osgi.internal.loader.BundleLoader;
+import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+
+public class DelegatingConnectClassLoader extends EquinoxClassLoader {
+ static {
+ try {
+ ClassLoader.registerAsParallelCapable();
+ } catch (Throwable t) {
+ // ignore any error
+ }
+ }
+ private final ClassLoader connectClassLoader;
+
+ public DelegatingConnectClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, Generation generation, ClassLoader connectClassLoader) {
+ super(parent, configuration, delegate, generation);
+ this.connectClassLoader = connectClassLoader;
+ }
+
+ @Override
+ public Class<?> findLocalClass(String classname) throws ClassNotFoundException {
+ if (connectClassLoader == null) {
+ throw new ClassNotFoundException();
+ }
+ return connectClassLoader.loadClass(classname);
+ }
+
+ @Override
+ public URL findLocalResource(String resource) {
+ if (connectClassLoader == null) {
+ return null;
+ }
+ return connectClassLoader.getResource(resource);
+ }
+
+ @Override
+ public Enumeration<URL> findLocalResources(String resource) {
+ if (connectClassLoader == null) {
+ return Collections.enumeration(Collections.<URL> emptyList());
+ }
+ try {
+ return connectClassLoader.getResources(resource);
+ } catch (IOException e) {
+ return Collections.enumeration(Collections.<URL> emptyList());
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/BundleContextImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/BundleContextImpl.java
index 0f059c8..29e9fa9 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/BundleContextImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/BundleContextImpl.java
@@ -15,10 +15,8 @@
package org.eclipse.osgi.internal.framework;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
-import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
@@ -182,14 +180,9 @@
@Override
public Bundle installBundle(String location, InputStream in) throws BundleException {
checkValid();
- try {
- URLConnection content = container.getStorage().getContentConnection(null, location, in);
- Generation generation = container.getStorage().install(bundle.getModule(), location, content);
- return generation.getRevision().getBundle();
- } catch (IOException e) {
- throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$
- }
+ Generation generation = container.getStorage().install(bundle.getModule(), location, in);
+ return generation.getRevision().getBundle();
}
/**
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java
index 2ea40c9..fe0c79a 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java
@@ -31,7 +31,9 @@
static final class Finder extends SecurityManager {
@Override
public Class<?>[] getClassContext() {
- return super.getClassContext();
+ Class<?>[] result = super.getClassContext();
+ // note that Android returns null, so handling this by returning empty
+ return result == null ? new Class[0] : result;
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/DTOBuilder.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/DTOBuilder.java
index 9607429..86ee2d0 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/DTOBuilder.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/DTOBuilder.java
@@ -15,17 +15,44 @@
package org.eclipse.osgi.internal.framework;
import java.lang.reflect.Array;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
import org.osgi.dto.DTO;
-import org.osgi.framework.*;
-import org.osgi.framework.dto.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.dto.BundleDTO;
+import org.osgi.framework.dto.FrameworkDTO;
+import org.osgi.framework.dto.ServiceReferenceDTO;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.osgi.framework.startlevel.dto.BundleStartLevelDTO;
import org.osgi.framework.startlevel.dto.FrameworkStartLevelDTO;
-import org.osgi.framework.wiring.*;
-import org.osgi.framework.wiring.dto.*;
-import org.osgi.resource.dto.*;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.dto.BundleRevisionDTO;
+import org.osgi.framework.wiring.dto.BundleWireDTO;
+import org.osgi.framework.wiring.dto.BundleWiringDTO;
+import org.osgi.framework.wiring.dto.FrameworkWiringDTO;
+import org.osgi.resource.dto.CapabilityDTO;
+import org.osgi.resource.dto.CapabilityRefDTO;
+import org.osgi.resource.dto.RequirementDTO;
+import org.osgi.resource.dto.RequirementRefDTO;
+import org.osgi.resource.dto.WireDTO;
public class DTOBuilder {
private final Map<BundleRevision, BundleRevisionDTO> resources;
@@ -318,7 +345,7 @@
size = references == null ? 0 : references.length;
List<ServiceReferenceDTO> refDTOs = newList(size);
for (int i = 0; i < size; i++) {
- ServiceReferenceDTO serviceRefDTO = getServiceReferenceDTO(references[i]);
+ ServiceReferenceDTO serviceRefDTO = newServiceReferenceDTO(references[i]);
if (serviceRefDTO != null) {
refDTOs.add(serviceRefDTO);
}
@@ -335,17 +362,12 @@
return (Map<String, Object>) m;
}
- private static ServiceReferenceDTO getServiceReferenceDTO(ServiceReference<?> ref) {
+ public static ServiceReferenceDTO newServiceReferenceDTO(ServiceReference<?> ref) {
if (ref == null) {
return null;
}
- Bundle b = ref.getBundle();
- if (b == null) {
- // service has been unregistered
- return null;
- }
+
ServiceReferenceDTO dto = new ServiceReferenceDTO();
- dto.bundle = b.getBundleId();
String[] keys = ref.getPropertyKeys();
Map<String, Object> properties = newMap(keys.length);
for (String k : keys) {
@@ -353,6 +375,9 @@
if (Constants.SERVICE_ID.equals(k)) {
dto.id = ((Long) v).longValue();
}
+ if (Constants.SERVICE_BUNDLEID.equals(k)) {
+ dto.bundle = ((Long) v).longValue();
+ }
properties.put(k, mapValue(v));
}
dto.properties = properties;
@@ -383,7 +408,7 @@
final int length = references.length;
List<ServiceReferenceDTO> refDTOs = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
- ServiceReferenceDTO dto = getServiceReferenceDTO(references[i]);
+ ServiceReferenceDTO dto = newServiceReferenceDTO(references[i]);
if (dto != null) {
refDTOs.add(dto);
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxBundle.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxBundle.java
index 3dbc4df..56c5eee 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxBundle.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxBundle.java
@@ -480,13 +480,9 @@
@Override
public void update(InputStream input) throws BundleException {
- try {
- Storage storage = equinoxContainer.getStorage();
- storage.update(module, storage.getContentConnection(module, null, input));
- signerInfos = null;
- } catch (IOException e) {
- throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$
- }
+ Storage storage = equinoxContainer.getStorage();
+ storage.update(module, input);
+ signerInfos = null;
}
@Override
@@ -971,7 +967,7 @@
}
/**
- * Check for permission to get a service.
+ * Check for permission to adapt.
*/
private <A> void checkAdaptPermission(Class<A> adapterType) {
SecurityManager sm = System.getSecurityManager();
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
index af1b7d0..04f6809 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
@@ -13,20 +13,29 @@
*******************************************************************************/
package org.eclipse.osgi.internal.framework;
+import java.io.File;
import java.io.IOException;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
+import java.net.URL;
import java.security.AccessController;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.eclipse.osgi.framework.eventmgr.ListenerQueue;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.framework.util.SecureAction;
+import org.eclipse.osgi.internal.connect.ConnectBundleFile;
+import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.legacy.PackageAdminImpl;
import org.eclipse.osgi.internal.framework.legacy.StartLevelImpl;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
@@ -36,7 +45,9 @@
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry;
import org.eclipse.osgi.signedcontent.SignedContentFactory;
+import org.eclipse.osgi.storage.BundleInfo;
import org.eclipse.osgi.storage.Storage;
+import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.AdminPermission;
@@ -44,6 +55,9 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectModule;
+import org.osgi.framework.connect.ModuleConnector;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
@@ -53,6 +67,7 @@
public static final String NAME = "org.eclipse.osgi"; //$NON-NLS-1$
static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
+ private final ConnectModules connectModules;
private final EquinoxConfiguration equinoxConfig;
private final EquinoxLogServices logServices;
private final Storage storage;
@@ -75,7 +90,7 @@
private ScheduledExecutorService executor;
private StorageSaver storageSaver;
- public EquinoxContainer(Map<String, ?> configuration) {
+ public EquinoxContainer(Map<String, ?> configuration, ModuleConnector moduleConnector) {
ClassLoader platformClassLoader = null;
try {
Method getPlatformClassLoader = ClassLoader.class.getMethod("getPlatformClassLoader"); //$NON-NLS-1$
@@ -89,6 +104,10 @@
this.equinoxConfig = new EquinoxConfiguration(configuration, new HookRegistry(this));
this.logServices = new EquinoxLogServices(this.equinoxConfig);
this.equinoxConfig.logMessages(this.logServices);
+ this.connectModules = new ConnectModules(moduleConnector);
+
+ initConnectFramework(moduleConnector, this.equinoxConfig);
+
this.equinoxConfig.getHookRegistry().initialize();
try {
this.storage = Storage.createStorage(this);
@@ -133,6 +152,17 @@
isProcessClassRecursionSupportedByAll = supportRecursion;
}
+ private static void initConnectFramework(ModuleConnector moduleConnector, EquinoxConfiguration equinoxConfig) {
+ if (moduleConnector == null) {
+ return;
+ }
+ URL configUrl = equinoxConfig.getEquinoxLocations().getConfigurationLocation().getURL();
+ final File fwkStore = new File(configUrl.getPath());
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ Map<String, String> config = (Map) equinoxConfig.getInitialConfig();
+ moduleConnector.initialize(fwkStore, Collections.unmodifiableMap(config));
+ }
+
public Storage getStorage() {
return storage;
}
@@ -331,4 +361,62 @@
public ClassLoader getBootLoader() {
return bootLoader;
}
+
+ public ConnectModules getConnectModules() {
+ return connectModules;
+ }
+
+ public static class ConnectModules {
+ final ModuleConnector moduleConnector;
+ private final ConcurrentMap<String, ConnectModule> connectModules = new ConcurrentHashMap<>();
+ private final WeakHashMap<ConnectContent, WeakReference<ConnectBundleFile>> contents = new WeakHashMap<>();
+
+ public ConnectModules(ModuleConnector moduleConnector) {
+ this.moduleConnector = moduleConnector;
+ }
+
+ public ConnectModule connect(String location) {
+ if (moduleConnector == null) {
+ return null;
+ }
+ ConnectModule result = connectModules.compute(location, (k, v) -> {
+ try {
+ return moduleConnector.connect(location).orElse(null);
+ } catch (BundleException e) {
+ throw new IllegalStateException(e);
+ }
+ });
+ return result;
+ }
+
+ public ConnectBundleFile getConnectBundleFile(ConnectModule module, File basefile,
+ BundleInfo.Generation generation, MRUBundleFileList mruList, Debug debug) throws IOException {
+ ConnectContent content = module.getContent();
+ synchronized (contents) {
+ WeakReference<ConnectBundleFile> ref = contents.get(content);
+ if (ref != null) {
+ ConnectBundleFile bundleFile = ref.get();
+ if (bundleFile != null) {
+ return bundleFile;
+ }
+ }
+ ConnectBundleFile bundleFile = new ConnectBundleFile(module, basefile, generation, mruList, debug);
+ contents.put(content, new WeakReference<>(bundleFile));
+ return bundleFile;
+ }
+ }
+
+ public ModuleConnector getModuleConnector() {
+ return moduleConnector;
+ }
+
+ public ConnectModule getConnectModule(String location) {
+ return connectModules.get(location);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
+ throw (E) e;
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
index d0ccb36..528eba6 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/FilterImpl.java
@@ -32,6 +32,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.messages.Msg;
@@ -514,17 +515,9 @@
if (value1 instanceof Collection<?>) {
return compare_Collection((Collection<?>) value1);
}
- if (value1 instanceof Integer) {
- return compare_Integer(((Integer) value1).intValue());
- }
- if (value1 instanceof Long) {
- return compare_Long(((Long) value1).longValue());
- }
- if (value1 instanceof Byte) {
- return compare_Byte(((Byte) value1).byteValue());
- }
- if (value1 instanceof Short) {
- return compare_Short(((Short) value1).shortValue());
+ if (value1 instanceof Integer || value1 instanceof Long || value1 instanceof Byte
+ || value1 instanceof Short) {
+ return compare_Long(((Number) value1).longValue());
}
if (value1 instanceof Character) {
return compare_Character(((Character) value1).charValue());
@@ -571,7 +564,7 @@
if (debug) {
Debug.println(operation() + "(" + value1 + "," + value() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
- if (compare_Integer(value1)) {
+ if (compare_Long(value1)) {
return true;
}
}
@@ -595,7 +588,7 @@
if (debug) {
Debug.println(operation() + "(" + value1 + "," + value() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
- if (compare_Byte(value1)) {
+ if (compare_Long(value1)) {
return true;
}
}
@@ -607,7 +600,7 @@
if (debug) {
Debug.println(operation() + "(" + value1 + "," + value() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
- if (compare_Short(value1)) {
+ if (compare_Long(value1)) {
return true;
}
}
@@ -684,10 +677,6 @@
return false;
}
- boolean compare_Byte(byte byteval) {
- return false;
- }
-
boolean compare_Character(char charval) {
return false;
}
@@ -700,18 +689,10 @@
return false;
}
- boolean compare_Integer(int intval) {
- return false;
- }
-
boolean compare_Long(long longval) {
return false;
}
- boolean compare_Short(short shortval) {
- return false;
- }
-
/**
* Encode the value string such that '(', '*', ')' and '\' are escaped.
*
@@ -864,12 +845,23 @@
static class Equal extends Item {
final String value;
+ private Object cached;
Equal(String attr, String value, boolean debug) {
super(attr, debug);
this.value = value;
}
+ private <T> T convert(Class<T> type, Function<String, ? extends T> converter) {
+ @SuppressWarnings("unchecked")
+ T converted = (T) cached;
+ if ((converted != null) && type.isInstance(converted)) {
+ return converted;
+ }
+ cached = converted = converter.apply(value.trim());
+ return converted;
+ }
+
@Override
String operation() {
return "EQUAL"; //$NON-NLS-1$
@@ -892,7 +884,7 @@
@Override
boolean compare_Version(Version value1) {
try {
- Version version2 = Version.valueOf(value);
+ Version version2 = convert(Version.class, Version::valueOf);
return comparison(value1.compareTo(version2));
} catch (Exception e) {
// if the valueOf or compareTo method throws an exception
@@ -902,22 +894,11 @@
@Override
boolean compare_Boolean(boolean boolval) {
- boolean boolval2 = Boolean.parseBoolean(value.trim());
+ boolean boolval2 = convert(Boolean.class, Boolean::valueOf).booleanValue();
return comparison(Boolean.compare(boolval, boolval2));
}
@Override
- boolean compare_Byte(byte byteval) {
- byte byteval2;
- try {
- byteval2 = Byte.parseByte(value.trim());
- } catch (IllegalArgumentException e) {
- return false;
- }
- return comparison(Byte.compare(byteval, byteval2));
- }
-
- @Override
boolean compare_Character(char charval) {
char charval2;
try {
@@ -932,7 +913,7 @@
boolean compare_Double(double doubleval) {
double doubleval2;
try {
- doubleval2 = Double.parseDouble(value.trim());
+ doubleval2 = convert(Double.class, Double::valueOf).doubleValue();
} catch (IllegalArgumentException e) {
return false;
}
@@ -943,7 +924,7 @@
boolean compare_Float(float floatval) {
float floatval2;
try {
- floatval2 = Float.parseFloat(value.trim());
+ floatval2 = convert(Float.class, Float::valueOf).floatValue();
} catch (IllegalArgumentException e) {
return false;
}
@@ -951,21 +932,10 @@
}
@Override
- boolean compare_Integer(int intval) {
- int intval2;
- try {
- intval2 = Integer.parseInt(value.trim());
- } catch (IllegalArgumentException e) {
- return false;
- }
- return comparison(Integer.compare(intval, intval2));
- }
-
- @Override
boolean compare_Long(long longval) {
long longval2;
try {
- longval2 = Long.parseLong(value.trim());
+ longval2 = convert(Long.class, Long::valueOf).longValue();
} catch (IllegalArgumentException e) {
return false;
}
@@ -973,17 +943,6 @@
}
@Override
- boolean compare_Short(short shortval) {
- short shortval2;
- try {
- shortval2 = Short.parseShort(value.trim());
- } catch (IllegalArgumentException e) {
- return false;
- }
- return comparison(Short.compare(shortval, shortval2));
- }
-
- @Override
boolean compare_Comparable(Comparable<Object> value1) {
Object value2 = valueOf(value1.getClass());
if (value2 == null) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/SystemBundleActivator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/SystemBundleActivator.java
index b1917a1..44e488c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/SystemBundleActivator.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/SystemBundleActivator.java
@@ -40,6 +40,7 @@
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.condition.Condition;
import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.permissionadmin.PermissionAdmin;
@@ -72,6 +73,11 @@
FrameworkDebugOptions dbgOptions = (FrameworkDebugOptions) configuration.getDebugOptions();
dbgOptions.start(bc);
+ Hashtable<String, Object> props = new Hashtable<>(7);
+ props.clear();
+
+ props.put(Condition.CONDITION_ID, Condition.CONDITION_ID_TRUE);
+ register(bc, Condition.class, Condition.INSTANCE, false, props);
SecurityAdmin sa = bundle.getEquinoxContainer().getStorage().getSecurityAdmin();
ClassLoader tccl = bundle.getEquinoxContainer().getContextFinder();
@@ -84,7 +90,7 @@
register(bc, PermissionAdmin.class, sa, null);
register(bc, ConditionalPermissionAdmin.class, sa, null);
- Hashtable<String, Object> props = new Hashtable<>(7);
+
props.clear();
props.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
register(bc, Resolver.class, new ResolverImpl(new Logger(0), null), false, props);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java
deleted file mode 100644
index 5bfb4e3..0000000
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/FrameworkUtilHelper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.internal.hookregistry;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-
-/**
- * The helper provides alternative implementations for methods in the
- * {@link FrameworkUtil} class. While this is not a hook, it is possible
- * for framework fragments to provide a META-INF/services configuration
- * to allow their own implementation to be loaded by the {@link FrameworkUtil}
- * class.
- */
-public class FrameworkUtilHelper {
- /**
- * See {@link FrameworkUtil#getBundle(Class)}
- * @param classFromBundle a class defined by a bundle class loader.
- * @return A Bundle for the specified bundle class or null if the
- * specified class was not defined by a bundle class loader.
- */
- public Bundle getBundle(Class<?> classFromBundle) {
- return null;
- }
-}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
index 552438a..5990f4c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/HookRegistry.java
@@ -24,6 +24,7 @@
import java.util.Properties;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.cds.CDSHookConfigurator;
+import org.eclipse.osgi.internal.connect.ConnectHookConfigurator;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hooks.DevClassLoadingHook;
@@ -106,6 +107,8 @@
List<FrameworkLogEntry> errors = new ArrayList<>(0); // optimistic that no errors will occur
mergeFileHookConfigurators(configurators, errors);
mergePropertyHookConfigurators(configurators);
+ // make sure to add connect configurator first always
+ configurators.add(0, ConnectHookConfigurator.class.getName());
synchronized (this) {
addClassLoaderHook(new DevClassLoadingHook(container.getConfiguration()));
addClassLoaderHook(new EclipseLazyStarter(container));
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
index 8a4eb82..8d26f1f 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
@@ -19,8 +19,11 @@
import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
-import org.eclipse.osgi.internal.loader.classpath.*;
+import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
+import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
+import org.eclipse.osgi.internal.loader.classpath.FragmentClasspath;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
public class DevClassLoadingHook extends ClassLoaderHook implements KeyedElement {
@@ -36,6 +39,10 @@
@Override
public boolean addClassPathEntry(ArrayList<ClasspathEntry> cpEntries, String cp, ClasspathManager hostmanager, Generation sourceGeneration) {
+ // if this is a connect bundle just ignore
+ if (sourceGeneration.getContentType() == Type.CONNECT) {
+ return false;
+ }
// first check that we are in devmode for this sourcedata
String[] devClassPaths = !configuration.inDevelopmentMode() ? null : configuration.getDevClassPath(sourceGeneration.getRevision().getSymbolicName());
if (devClassPaths == null || devClassPaths.length == 0)
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java
index 556b07e..021a79e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java
@@ -22,7 +22,6 @@
import org.eclipse.osgi.internal.framework.EquinoxBundle;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.loader.BundleLoader;
-import org.eclipse.osgi.internal.loader.SystemBundleLoader;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.service.packageadmin.PackageAdmin;
@@ -114,78 +113,111 @@
* @param container the equinox container
* @return true if assignable given package wiring
*/
- public static boolean isServiceAssignableTo(Bundle registrant, Bundle client, String className, Class<?> serviceClass, EquinoxContainer container) {
+ public static boolean isServiceAssignableTo(Bundle registrant, Bundle client, String className,
+ Class<?> serviceClass, boolean checkInternal, EquinoxContainer container) {
// 1) if the registrant == client always return true
if (registrant == client) {
return true;
}
// 2) get the package name from the specified className
String pkgName = BundleLoader.getPackageName(className);
- if (pkgName.startsWith("java.")) //$NON-NLS-1$
+ if (pkgName.startsWith("java.")) { //$NON-NLS-1$
return true;
+ }
BundleLoader producerBL = getBundleLoader(registrant);
- if (producerBL == null)
+ if (producerBL == null) {
return false;
- BundleLoader consumerBL = getBundleLoader(client);
- if (consumerBL == null)
- return false;
- // 3) for the specified bundle, find the wiring for the package. If no wiring is found return true
- PackageSource consumerSource = consumerBL.getPackageSource(pkgName);
- if (consumerSource == null)
- return true;
- // work around the issue when the package is in the EE and we delegate to boot for that package
- if (container.isBootDelegationPackage(pkgName)) {
- Bundle systemBundle = container.getStorage().getModuleContainer().getModule(0).getBundle();
- SystemBundleLoader systemLoader = (SystemBundleLoader) getBundleLoader(systemBundle);
- if (systemLoader.isExportedPackage(pkgName)) {
- return true; // in this case we have a common source from the EE
- }
}
+ BundleLoader consumerBL = getBundleLoader(client);
+ if (consumerBL == null) {
+ return false;
+ }
+ // 3) for the specified bundle, find the wiring for the package. If no wiring is found return true
+ PackageSource consumerSource = getSourceFromLoader(consumerBL, pkgName, className, checkInternal);
+ if (consumerSource == null) {
+ // confirmed no source for consumer
+ return true;
+ }
+ // if boot delegate just return true
+ if (container.isBootDelegationPackage(pkgName)) {
+ return true;
+ }
+
// 4) For the registrant bundle, find the wiring for the package.
- PackageSource producerSource = producerBL.getPackageSource(pkgName);
+ PackageSource producerSource = getSourceFromLoader(producerBL, pkgName, className, checkInternal);
if (producerSource == null) {
+ // confirmed no local class either; now check service object
if (serviceClass != null && ServiceFactory.class.isAssignableFrom(serviceClass)) {
@SuppressWarnings("deprecation")
Bundle bundle = container.getPackageAdmin().getBundle(serviceClass);
- if (bundle != null && bundle != registrant)
+ if (bundle != null && bundle != registrant) {
// in this case we have a wacky ServiceFactory that is doing something we cannot
- // verify if it is correct. Instead of failing we allow the assignment and hope for the best
+ // verify if it is correct. Instead of failing we allow the assignment and hope
+ // for the best
// bug 326918
return true;
+ }
}
- // 5) If no wiring is found for the registrant bundle then find the wiring for the classloader of the service object. If no wiring is found return false.
- producerSource = getPackageSource(serviceClass, pkgName, container.getPackageAdmin());
- if (producerSource == null)
+ // 5) If no wiring is found for the registrant bundle then find the wiring for
+ // the classloader of the service object. If no wiring is found return false.
+ producerSource = getPackageSource(serviceClass, pkgName, className, checkInternal,
+ container.getPackageAdmin());
+ if (producerSource == null) {
return false;
+ }
}
// 6) If the two wirings found are equal then return true; otherwise return false.
return producerSource.hasCommonSource(consumerSource);
}
- private static PackageSource getPackageSource(Class<?> serviceClass, String pkgName, @SuppressWarnings("deprecation") PackageAdmin packageAdmin) {
- if (serviceClass == null)
+ private static PackageSource getSourceFromLoader(BundleLoader loader, String pkgName, String className,
+ boolean checkInternal) {
+ PackageSource source = loader.getPackageSource(pkgName);
+ if (source != null || !checkInternal) {
+ return source;
+ }
+ try {
+ if (loader.findLocalClass(className) != null) {
+ // create a source that represents the private package
+ return (new SingleSourcePackage(pkgName, loader));
+ }
+ } catch (ClassNotFoundException e) {
+ // ignore
+ }
+ return null;
+ }
+
+ private static PackageSource getPackageSource(Class<?> serviceClass, String pkgName, String className,
+ boolean checkInternal,
+ @SuppressWarnings("deprecation") PackageAdmin packageAdmin) {
+ if (serviceClass == null) {
return null;
+ }
@SuppressWarnings("deprecation")
Bundle serviceBundle = packageAdmin.getBundle(serviceClass);
- if (serviceBundle == null)
+ if (serviceBundle == null) {
return null;
+ }
BundleLoader producerBL = getBundleLoader(serviceBundle);
- if (producerBL == null)
+ if (producerBL == null) {
return null;
- PackageSource producerSource = producerBL.getPackageSource(pkgName);
- if (producerSource != null)
+ }
+ PackageSource producerSource = getSourceFromLoader(producerBL, pkgName, className, checkInternal);
+ if (producerSource != null) {
return producerSource;
+ }
// try the interfaces
Class<?>[] interfaces = serviceClass.getInterfaces();
// note that getInterfaces never returns null
for (Class<?> intf : interfaces) {
- producerSource = getPackageSource(intf, pkgName, packageAdmin);
- if (producerSource != null)
+ producerSource = getPackageSource(intf, pkgName, className, checkInternal, packageAdmin);
+ if (producerSource != null) {
return producerSource;
+ }
}
// try super class
- return getPackageSource(serviceClass.getSuperclass(), pkgName, packageAdmin);
+ return getPackageSource(serviceClass.getSuperclass(), pkgName, className, checkInternal, packageAdmin);
}
private static BundleLoader getBundleLoader(Bundle bundle) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java
index fe62d5a..7ff945e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java
@@ -13,8 +13,12 @@
*******************************************************************************/
package org.eclipse.osgi.internal.log;
-import java.util.*;
-import org.osgi.framework.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -42,8 +46,8 @@
}
public void start() {
- eventAdminTracker.open();
- eventHandlerTracker.open();
+ eventAdminTracker.open(true);
+ eventHandlerTracker.open(true);
}
public void stop() {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/implied.permissions b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/implied.permissions
index 50f98ad..9273890 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/implied.permissions
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/implied.permissions
@@ -53,3 +53,5 @@
(org.osgi.framework.CapabilityPermission "osgi.ee" "require")
# Added for OSGi R6
(org.osgi.framework.CapabilityPermission "osgi.native" "require")
+# Added for OSGi R8
+(org.osgi.framework.ServicePermission "org.osgi.service.condition.Condition" "get")
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java
index 7468872..e57ae09 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java
@@ -17,7 +17,14 @@
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.BundleContextImpl;
import org.eclipse.osgi.internal.framework.FilterImpl;
-import org.osgi.framework.*;
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.UnfilteredServiceListener;
import org.osgi.framework.hooks.service.ListenerHook;
/**
@@ -104,7 +111,7 @@
if (event == null) {
return;
}
- if (allservices || ServiceRegistry.isAssignableTo(context, reference)) {
+ if (allservices || ServiceRegistry.isAssignableTo(context, objectClass, reference)) {
if (debug.DEBUG_EVENTS) {
String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
Debug.println("dispatchFilteredServiceEvent(" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java
index 3cafc16..f04cf42 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java
@@ -15,7 +15,14 @@
package org.eclipse.osgi.internal.serviceregistry;
import java.util.Dictionary;
-import org.osgi.framework.*;
+import org.eclipse.osgi.internal.framework.DTOBuilder;
+import org.osgi.framework.AdaptPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.dto.ServiceReferenceDTO;
/**
* A reference to a service.
@@ -175,7 +182,7 @@
*/
@Override
public boolean isAssignableTo(Bundle bundle, String className) {
- return registration.isAssignableTo(bundle, className);
+ return registration.isAssignableTo(bundle, className, true);
}
/**
@@ -318,4 +325,22 @@
public Dictionary<String, Object> getProperties() {
return registration.getPropertiesCopy();
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <A> A adapt(Class<A> type) {
+ checkAdaptPermission(type);
+ if (ServiceReferenceDTO.class.equals(type)) {
+ return (A) DTOBuilder.newServiceReferenceDTO(this);
+ }
+ return null;
+ }
+
+ private <A> void checkAdaptPermission(Class<A> adapterType) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ return;
+ }
+ sm.checkPermission(new AdaptPermission(adapterType.getName(), registration.getRegisteringBundle(), AdaptPermission.ADAPT));
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java
index 0d1e51e..a0dc562 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java
@@ -709,8 +709,9 @@
}
}
- boolean isAssignableTo(Bundle client, String className) {
- return PackageSource.isServiceAssignableTo(bundle, client, className, service.getClass(), context.getContainer());
+ boolean isAssignableTo(Bundle client, String className, boolean checkInternal) {
+ return PackageSource.isServiceAssignableTo(bundle, client, className, service.getClass(), checkInternal,
+ context.getContainer());
}
/**
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java
index 934cc0c..4cdcd97 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java
@@ -383,7 +383,7 @@
} catch (IllegalStateException e) {
continue; // got unregistered, don't return reference
}
- if (allservices || isAssignableTo(context, reference)) {
+ if (allservices || isAssignableTo(context, clazz, reference)) {
try { /* test for permission to get the service */
checkGetServicePermission(reference);
} catch (SecurityException se) {
@@ -1206,11 +1206,11 @@
return true;
}
- static boolean isAssignableTo(BundleContextImpl context, ServiceReferenceImpl<?> reference) {
+ static boolean isAssignableTo(BundleContextImpl context, String clazz, ServiceReferenceImpl<?> reference) {
Bundle bundle = context.getBundleImpl();
String[] clazzes = reference.getClasses();
for (int i = 0, len = clazzes.length; i < len; i++)
- if (!reference.isAssignableTo(bundle, clazzes[i]))
+ if (!reference.getRegistration().isAssignableTo(bundle, clazzes[i], clazzes[i] == clazz))
return false;
return true;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
index defe49a..bef43d0 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
@@ -105,7 +105,7 @@
// Step 1, verify the .SF file is signed by the private key that corresponds to the public key
// in the .RSA/.DSA file
- String baseFile = bf.getBaseFile() != null ? bf.getBaseFile().toString() : null;
+ String baseFile = String.valueOf(bf.getBaseFile());
PKCS7Processor processor = new PKCS7Processor(pkcs7Bytes, 0, pkcs7Bytes.length, signer, baseFile);
// call the Step 1 in the Jar File Verification algorithm
processor.verifySFSignature(sfBytes, 0, sfBytes.length);
@@ -169,7 +169,7 @@
// check if the the computed digest value of manifest file equals to the digest value in the .sf file
if (!digestValue.equals(manifestDigest)) {
- SignatureException se = new SignatureException(NLS.bind(SignedContentMessages.Security_File_Is_Tampered, new String[] {signedBundle.getBaseFile().toString()}));
+ SignatureException se = new SignatureException(NLS.bind(SignedContentMessages.Security_File_Is_Tampered, new String[] {String.valueOf(signedBundle.getBaseFile())}));
signedBundleHook.log(se.getMessage(), FrameworkLogEntry.ERROR, se);
throw se;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
index 7e9d88c..5f3cf84 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
@@ -17,11 +17,20 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.security.*;
-import java.security.cert.*;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
import java.util.Date;
-import org.eclipse.osgi.signedcontent.*;
-import org.eclipse.osgi.storage.bundlefile.*;
+import org.eclipse.osgi.signedcontent.SignedContent;
+import org.eclipse.osgi.signedcontent.SignedContentEntry;
+import org.eclipse.osgi.signedcontent.SignerInfo;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
import org.eclipse.osgi.util.NLS;
/**
@@ -73,7 +82,7 @@
// double check that no signer thinks it should exist
SignedContentEntry signedEntry = signedContent.getSignedEntry(path);
if (signedEntry != null)
- throw new SecurityException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, path, getBaseFile().toString()));
+ throw new SecurityException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, path, String.valueOf(getBaseFile())));
return null;
}
return new SignedBundleEntry(be);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
index 5b741d0..f8acc8d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
@@ -196,7 +196,7 @@
exception = e;
}
if (entry == null)
- throw new InvalidContentException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, entryName, currentContent.getBaseFile().toString()), exception);
+ throw new InvalidContentException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, entryName, String.valueOf(currentContent.getBaseFile())), exception);
if (entry.getSize() > VERIFY_LIMIT) {
try (InputStream in = entry.getInputStream()) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
index 049334f..901df37 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/Equinox.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2013 IBM Corporation and others.
+ * Copyright (c) 2008, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,12 +13,24 @@
*******************************************************************************/
package org.eclipse.osgi.launch;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.security.cert.X509Certificate;
-import java.util.*;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.connect.ModuleConnector;
import org.osgi.framework.launch.Framework;
/**
@@ -31,7 +43,14 @@
private final Framework systemBundle;
public Equinox(Map<String, ?> configuration) {
- EquinoxContainer container = new EquinoxContainer(configuration);
+ this(configuration, null);
+ }
+
+ /**
+ * @since 3.16
+ */
+ public Equinox(Map<String, ?> configuration, ModuleConnector moduleConnector) {
+ EquinoxContainer container = new EquinoxContainer(configuration, moduleConnector);
systemBundle = (Framework) container.getStorage().getModuleContainer().getModule(0).getBundle();
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
index 17d9c04..fd1ad8a 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/launch/EquinoxFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2012 IBM Corporation and others.
+ * Copyright (c) 2009, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,6 +14,8 @@
package org.eclipse.osgi.launch;
import java.util.Map;
+import org.osgi.framework.connect.ConnectFrameworkFactory;
+import org.osgi.framework.connect.ModuleConnector;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -21,11 +23,15 @@
* The framework factory implementation for the Equinox framework.
* @since 3.5
*/
-public class EquinoxFactory implements FrameworkFactory {
+public class EquinoxFactory implements FrameworkFactory, ConnectFrameworkFactory {
@Override
public Framework newFramework(Map<String, String> configuration) {
- return new Equinox(configuration);
+ return newFramework(configuration, null);
}
+ @Override
+ public Framework newFramework(Map<String, String> configuration, ModuleConnector moduleConnector) {
+ return new Equinox(configuration, moduleConnector);
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
index 60133ef..ee5caae 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
@@ -38,6 +38,7 @@
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap;
import org.eclipse.osgi.framework.util.ThreadInfoReport;
+import org.eclipse.osgi.internal.connect.ConnectBundleFile;
import org.eclipse.osgi.internal.container.LockSet;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
@@ -45,15 +46,18 @@
import org.eclipse.osgi.internal.hookregistry.StorageHookFactory;
import org.eclipse.osgi.internal.hookregistry.StorageHookFactory.StorageHook;
import org.eclipse.osgi.internal.messages.Msg;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.Storage.StorageException;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain;
import org.eclipse.osgi.storage.url.BundleResourceHandler;
import org.eclipse.osgi.storage.url.bundleentry.Handler;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.connect.ConnectModule;
public final class BundleInfo {
public static final String OSGI_BUNDLE_MANIFEST = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
@@ -67,7 +71,6 @@
private final Dictionary<String, String> cachedHeaders;
private File content;
private boolean isDirectory;
- private boolean isReference;
private boolean hasPackageInfo;
private BundleFile bundleFile;
private Map<String, String> rawHeaders;
@@ -78,17 +81,18 @@
private List<StorageHook<?, ?>> storageHooks;
private long lastModified;
private boolean isMRJar;
+ private Type contentType;
Generation(long generationId) {
this.generationId = generationId;
this.cachedHeaders = new CachedManifest(this, Collections.<String, String> emptyMap());
}
- Generation(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
+ Generation(long generationId, File content, boolean isDirectory, Type contentType, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
this.generationId = generationId;
this.content = content;
this.isDirectory = isDirectory;
- this.isReference = isReference;
+ this.contentType = contentType;
this.hasPackageInfo = hasPackageInfo;
this.cachedHeaders = new CachedManifest(this, cached);
this.lastModified = lastModified;
@@ -98,7 +102,7 @@
public BundleFile getBundleFile() {
synchronized (genMonitor) {
if (bundleFile == null) {
- if (getBundleId() == 0 && content == null) {
+ if (getBundleId() == 0 && content == null && contentType != Type.CONNECT) {
bundleFile = new SystemBundleFile();
} else {
bundleFile = getStorage().createBundleFile(content, this, isDirectory, true);
@@ -127,7 +131,20 @@
Map<String, String> getRawHeaders() {
synchronized (genMonitor) {
if (rawHeaders == null) {
- BundleEntry manifest = getBundleFile().getEntry(OSGI_BUNDLE_MANIFEST);
+ BundleFile bFile = getBundleFile();
+
+ if (this.contentType == Type.CONNECT) {
+ ConnectBundleFile connectContent = bFile instanceof BundleFileWrapperChain ? //
+ ((BundleFileWrapperChain) bFile).getWrappedType(ConnectBundleFile.class) : //
+ (ConnectBundleFile) bFile;
+
+ Map<String, String> connectHeaders = connectContent.getConnectHeaders();
+ if (connectHeaders != null) {
+ return rawHeaders = connectHeaders;
+ }
+ }
+
+ BundleEntry manifest = bFile.getEntry(OSGI_BUNDLE_MANIFEST);
if (manifest == null) {
rawHeaders = Collections.emptyMap();
} else {
@@ -211,12 +228,6 @@
}
}
- public boolean isReference() {
- synchronized (this.genMonitor) {
- return this.isReference;
- }
- }
-
public boolean hasPackageInfo() {
synchronized (this.genMonitor) {
return this.hasPackageInfo;
@@ -235,11 +246,25 @@
}
}
- void setContent(File content, boolean isReference) {
+ public Type getContentType() {
+ synchronized (this.genMonitor) {
+ return this.contentType;
+ }
+ }
+
+ void setContent(File content, Type contentType) {
+ if (getBundleId() == 0) {
+ // check connect for content first
+ ConnectModule connected = getStorage().getEquinoxContainer().getConnectModules().connect(getLocation());
+ if (connected != null) {
+ content = null;
+ contentType = Type.CONNECT;
+ }
+ }
synchronized (this.genMonitor) {
this.content = content;
this.isDirectory = content == null ? false : Storage.secureAction.isDirectory(content);
- this.isReference = isReference;
+ this.contentType = contentType;
setLastModified(content);
}
}
@@ -485,9 +510,9 @@
}
}
- Generation restoreGeneration(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
+ Generation restoreGeneration(long generationId, File content, boolean isDirectory, Type contentType, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
synchronized (this.infoMonitor) {
- Generation restoredGeneration = new Generation(generationId, content, isDirectory, isReference, hasPackageInfo, cached, lastModified, isMRJar);
+ Generation restoredGeneration = new Generation(generationId, content, isDirectory, contentType, hasPackageInfo, cached, lastModified, isMRJar);
return restoredGeneration;
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java
new file mode 100644
index 0000000..50f3f34
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.storage;
+
+import java.io.File;
+import org.osgi.framework.BundleException;
+
+/**
+ * A content provider is a marker interface that is used
+ * but the framework internally to handle different kinds of
+ * bundles. For example, reference installed bundles or
+ * connect bundles. The type of the provider indicates
+ * how the framework will handle the install or update
+ * of the bundle content.
+ */
+public interface ContentProvider {
+
+ /**
+ * The type of the provided content
+ */
+ public enum Type {
+ REFERENCE, CONNECT, DEFAULT;
+ }
+
+ /**
+ * A file of the content, may be {@code null}
+ * @return the file, may be {@code null}
+ * @throws BundleException
+ */
+ File getContent() throws BundleException;
+
+ /**
+ * The type of content
+ * @return the type of content
+ */
+ Type getType();
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
index 3013700..fba1658 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
@@ -39,6 +39,7 @@
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.internal.url.MultiplexingFactory;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@@ -181,6 +182,11 @@
* @return a list of classpath files for an extension bundle
*/
private File[] getExtensionFiles(ModuleRevision revision) {
+ Generation generation = (Generation) revision.getRevisionInfo();
+ if (generation.getContentType() == Type.CONNECT) {
+ // Don't do anything for connect bundles
+ return new File[0];
+ }
List<ModuleCapability> metaDatas = revision.getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE);
@SuppressWarnings("unchecked")
List<String> paths = metaDatas.isEmpty() ? null : (List<String>) metaDatas.get(0).getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_CLASSPATH);
@@ -238,7 +244,9 @@
current = new ArrayMap<>(hookActivators.getKeys(), hookActivators.getValues());
hookActivators.clear();
}
- for (BundleActivator activator : current) {
+ // indexing into the current collection the hard way to reverse de-activation
+ for (int i = current.getKeys().size() - 1; i >= 0; i--) {
+ BundleActivator activator = current.getKey(i);
try {
activator.stop(context);
} catch (Exception e) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
index e6933f0..22a91e2 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
@@ -83,6 +83,7 @@
import org.eclipse.osgi.internal.url.URLStreamHandlerFactoryImpl;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
@@ -92,7 +93,6 @@
import org.eclipse.osgi.storage.bundlefile.NestedDirBundleFile;
import org.eclipse.osgi.storage.bundlefile.ZipBundleFile;
import org.eclipse.osgi.storage.url.reference.Handler;
-import org.eclipse.osgi.storage.url.reference.ReferenceInputStream;
import org.eclipse.osgi.storagemanager.ManagedOutputStream;
import org.eclipse.osgi.storagemanager.StorageManager;
import org.eclipse.osgi.util.ManifestElement;
@@ -104,6 +104,7 @@
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
+import org.osgi.framework.connect.ConnectModule;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.NativeNamespace;
import org.osgi.framework.namespace.PackageNamespace;
@@ -135,9 +136,10 @@
}
- public static final int VERSION = 5;
- private static final int MR_JAR_VERSION = 4;
+ public static final int VERSION = 6;
+ private static final int CONTENT_TYPE_VERSION = 6;
private static final int CACHED_SYSTEM_CAPS_VERION = 5;
+ private static final int MR_JAR_VERSION = 4;
private static final int LOWEST_VERSION_SUPPORTED = 3;
public static final String BUNDLE_DATA_DIR = "data"; //$NON-NLS-1$
public static final String BUNDLE_FILE_NAME = "bundleFile"; //$NON-NLS-1$
@@ -186,8 +188,9 @@
}
private Storage(EquinoxContainer container, String[] cachedInfo) throws IOException {
- // default to Java 7 since that is our min
- Version javaVersion = Version.valueOf("1.7"); //$NON-NLS-1$
+ // default to Java 8 since that is our min
+ Version defaultVersion = Version.valueOf("1.8"); //$NON-NLS-1$
+ Version javaVersion = defaultVersion;
// set the profile and EE based off of the java.specification.version
String javaSpecVersionProp = System.getProperty(EquinoxConfiguration.PROP_JVM_SPEC_VERSION);
StringTokenizer st = new StringTokenizer(javaSpecVersionProp, " _-"); //$NON-NLS-1$
@@ -202,6 +205,12 @@
} catch (IllegalArgumentException e) {
// do nothing
}
+ if (javaVersion.compareTo(defaultVersion) < 0) {
+ // the Java specification property is wrong, we are compiled to the
+ // defaultVersion
+ // just use it instead.
+ javaVersion = defaultVersion;
+ }
runtimeVersion = javaVersion;
javaSpecVersion = javaSpecVersionProp;
mruList = new MRUBundleFileList(getBundleFileLimit(container.getConfiguration()), container.getConfiguration().getDebug());
@@ -364,6 +373,9 @@
}
}
File content = generation.getContent();
+ if (content == null) {
+ return false;
+ }
if (getConfiguration().inCheckConfigurationMode()) {
if (generation.isDirectory()) {
content = new File(content, "META-INF/MANIFEST.MF"); //$NON-NLS-1$
@@ -386,7 +398,7 @@
newGeneration = info.createGeneration();
File contentFile = getSystemContent();
- newGeneration.setContent(contentFile, false);
+ newGeneration.setContent(contentFile, Type.DEFAULT);
// First we must make sure the VM profile has been loaded
loadVMProfile(newGeneration);
@@ -412,7 +424,7 @@
File contentFile = currentGeneration.getContent();
if (systemNeedsUpdate(contentFile, currentRevision, currentGeneration, extraCapabilities, extraExports, cachedInfo)) {
newGeneration = currentGeneration.getBundleInfo().createGeneration();
- newGeneration.setContent(contentFile, false);
+ newGeneration.setContent(contentFile, Type.DEFAULT);
ModuleRevisionBuilder newBuilder = getBuilder(newGeneration, extraCapabilities, extraExports);
moduleContainer.update(systemModule, newBuilder, newGeneration);
moduleContainer.refresh(Collections.singleton(systemModule));
@@ -565,41 +577,47 @@
return osgiLocation.isReadOnly();
}
- public URLConnection getContentConnection(Module module, String bundleLocation, final InputStream in) throws IOException {
- List<StorageHookFactory<?, ?, ?>> storageHooks = getConfiguration().getHookRegistry().getStorageHookFactories();
- for (StorageHookFactory<?, ?, ?> storageHook : storageHooks) {
- URLConnection hookContent = storageHook.handleContentConnection(module, bundleLocation, in);
- if (hookContent != null) {
- return hookContent;
- }
- }
-
- if (in != null) {
- return new URLConnection(null) {
- /**
- * @throws IOException
- */
- @Override
- public void connect() throws IOException {
- connected = true;
+ public URLConnection getContentConnection(Module module, String bundleLocation, final InputStream in)
+ throws BundleException {
+ try {
+ List<StorageHookFactory<?, ?, ?>> storageHooks = getConfiguration().getHookRegistry()
+ .getStorageHookFactories();
+ for (StorageHookFactory<?, ?, ?> storageHook : storageHooks) {
+ URLConnection hookContent = storageHook.handleContentConnection(module, bundleLocation, in);
+ if (hookContent != null) {
+ return hookContent;
}
-
- /**
- * @throws IOException
- */
- @Override
- public InputStream getInputStream() throws IOException {
- return (in);
- }
- };
- }
- if (module == null) {
- if (bundleLocation == null) {
- throw new IllegalArgumentException("Module and location cannot be null"); //$NON-NLS-1$
}
- return getContentConnection(bundleLocation);
+
+ if (in != null) {
+ return new URLConnection(null) {
+ /**
+ * @throws IOException
+ */
+ @Override
+ public void connect() throws IOException {
+ connected = true;
+ }
+
+ /**
+ * @throws IOException
+ */
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return (in);
+ }
+ };
+ }
+ if (module == null) {
+ if (bundleLocation == null) {
+ throw new IllegalArgumentException("Module and location cannot be null"); //$NON-NLS-1$
+ }
+ return getContentConnection(bundleLocation);
+ }
+ return getContentConnection(getUpdateLocation(module));
+ } catch (IOException e) {
+ throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$
}
- return getContentConnection(getUpdateLocation(module));
}
private String getUpdateLocation(final Module module) {
@@ -651,7 +669,8 @@
return new URL(spec);
}
- public Generation install(Module origin, String bundleLocation, URLConnection content) throws BundleException {
+ public Generation install(Module origin, String bundleLocation, InputStream toInstall) throws BundleException {
+ URLConnection content = getContentConnection(null, bundleLocation, toInstall);
if (osgiLocation.isReadOnly()) {
throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION); //$NON-NLS-1$
}
@@ -689,16 +708,18 @@
return (Generation) existingLocation.getCurrentRevision().getRevisionInfo();
}
- boolean isReference = in instanceof ReferenceInputStream;
- File staged = stageContent(in, sourceURL);
+ ContentProvider contentProvider = getContentProvider(in, sourceURL);
+ Type contentType = contentProvider.getType();
+ File staged = contentProvider.getContent();
+
Generation generation = null;
try {
Long nextID = moduleDatabase.getAndIncrementNextId();
BundleInfo info = new BundleInfo(this, nextID, bundleLocation, 0);
generation = info.createGeneration();
- File contentFile = getContentFile(staged, isReference, nextID, generation.getGenerationId());
- generation.setContent(contentFile, isReference);
+ File contentFile = getContentFile(staged, contentType, nextID, generation.getGenerationId());
+ generation.setContent(contentFile, contentType);
// Check that we can open the bundle file
generation.getBundleFile().open();
setStorageHooks(generation);
@@ -714,7 +735,7 @@
}
return generation;
} catch (Throwable t) {
- if (!isReference) {
+ if (contentType == Type.DEFAULT) {
try {
delete(staged);
} catch (IOException e) {
@@ -744,6 +765,24 @@
}
}
+ ContentProvider getContentProvider(final InputStream in, final URL sourceURL) {
+ if (in instanceof ContentProvider) {
+ return (ContentProvider) in;
+ }
+ return new ContentProvider() {
+
+ @Override
+ public Type getType() {
+ return Type.DEFAULT;
+ }
+
+ @Override
+ public File getContent() throws BundleException {
+ return stageContent(in, sourceURL);
+ }
+ };
+ }
+
private void setStorageHooks(Generation generation) throws BundleException {
if (generation.getBundleInfo().getBundleId() == 0) {
return; // ignore system bundle
@@ -881,7 +920,11 @@
ModuleRevision current = module.getCurrentRevision();
Generation currentGen = (Generation) current.getRevisionInfo();
File content = currentGen.getContent();
- String spec = (currentGen.isReference() ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$
+ if (content == null) {
+ // TODO Handle connect bundle
+ return;
+ }
+ String spec = (currentGen.getContentType() == Type.REFERENCE ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$
URLConnection contentConn;
try {
contentConn = getContentConnection(spec);
@@ -891,7 +934,12 @@
update(module, contentConn);
}
- public Generation update(Module module, URLConnection content) throws BundleException {
+ public Generation update(Module module, InputStream updateIn) throws BundleException {
+ return update(module, getContentConnection(module, null, updateIn));
+ }
+
+ private Generation update(Module module, URLConnection content) throws BundleException {
+
if (osgiLocation.isReadOnly()) {
throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION); //$NON-NLS-1$
}
@@ -902,8 +950,11 @@
} catch (Throwable e) {
throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$
}
- boolean isReference = in instanceof ReferenceInputStream;
- File staged = stageContent(in, sourceURL);
+
+ ContentProvider contentProvider = getContentProvider(in, sourceURL);
+ Type contentType = contentProvider.getType();
+ File staged = contentProvider.getContent();
+
ModuleRevision current = module.getCurrentRevision();
Generation currentGen = (Generation) current.getRevisionInfo();
@@ -911,8 +962,8 @@
Generation newGen = bundleInfo.createGeneration();
try {
- File contentFile = getContentFile(staged, isReference, bundleInfo.getBundleId(), newGen.getGenerationId());
- newGen.setContent(contentFile, isReference);
+ File contentFile = getContentFile(staged, contentType, bundleInfo.getBundleId(), newGen.getGenerationId());
+ newGen.setContent(contentFile, contentType);
// Check that we can open the bundle file
newGen.getBundleFile().open();
setStorageHooks(newGen);
@@ -920,7 +971,7 @@
ModuleRevisionBuilder builder = getBuilder(newGen);
moduleContainer.update(module, builder, newGen);
} catch (Throwable t) {
- if (!isReference) {
+ if (contentType == Type.DEFAULT) {
try {
delete(staged);
} catch (IOException e) {
@@ -946,14 +997,14 @@
return newGen;
}
- private File getContentFile(final File staged, final boolean isReference, final long bundleID, final long generationID) throws BundleException {
+ private File getContentFile(final File staged, Type contentType, final long bundleID, final long generationID) throws BundleException {
if (System.getSecurityManager() == null)
- return getContentFile0(staged, isReference, bundleID, generationID);
+ return getContentFile0(staged, contentType, bundleID, generationID);
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
@Override
public File run() throws BundleException {
- return getContentFile0(staged, isReference, bundleID, generationID);
+ return getContentFile0(staged, contentType, bundleID, generationID);
}
});
} catch (PrivilegedActionException e) {
@@ -963,9 +1014,10 @@
}
}
- File getContentFile0(File staged, boolean isReference, long bundleID, long generationID) throws BundleException {
- File contentFile;
- if (!isReference) {
+ File getContentFile0(File staged, Type contentType, long bundleID, long generationID) throws BundleException {
+ File contentFile = staged;
+
+ if (contentType == Type.DEFAULT) {
File generationRoot = new File(childRoot, bundleID + "/" + generationID); //$NON-NLS-1$
generationRoot.mkdirs();
if (!generationRoot.isDirectory()) {
@@ -978,8 +1030,6 @@
throw new BundleException("Error while renaming bundle file to final location: " + contentFile, //$NON-NLS-1$
BundleException.READ_ERROR, e);
}
- } else {
- contentFile = staged;
}
return contentFile;
}
@@ -1058,7 +1108,7 @@
return result;
}
- private File stageContent(final InputStream in, final URL sourceURL) throws BundleException {
+ File stageContent(final InputStream in, final URL sourceURL) throws BundleException {
if (System.getSecurityManager() == null)
return stageContent0(in, sourceURL);
try {
@@ -1078,10 +1128,6 @@
File stageContent0(InputStream in, URL sourceURL) throws BundleException {
File outFile = null;
try {
- if (in instanceof ReferenceInputStream) {
- return ((ReferenceInputStream) in).getReference();
- }
-
outFile = File.createTempFile(BUNDLE_FILE_NAME, ".tmp", childRoot); //$NON-NLS-1$
String protocol = sourceURL == null ? null : sourceURL.getProtocol();
@@ -1138,9 +1184,16 @@
}
public BundleFile createBundleFile(File content, Generation generation, boolean isDirectory, boolean isBase) {
- BundleFile result;
+ BundleFile result = null;
+ ConnectModule connectModule = null;
+ if (generation.getContentType() == Type.CONNECT) {
+ connectModule = equinoxContainer.getConnectModules().getConnectModule(generation.getBundleInfo().getLocation());
+ }
try {
- if (isDirectory) {
+ if (connectModule != null && isBase) {
+ result = equinoxContainer.getConnectModules().getConnectBundleFile(connectModule, content, generation,
+ mruList, getConfiguration().getDebug());
+ } else if (isDirectory) {
boolean strictPath = Boolean.parseBoolean(equinoxContainer.getConfiguration().getConfiguration(EquinoxConfiguration.PROPERTY_STRICT_BUNDLE_ENTRY_PATH, Boolean.FALSE.toString()));
result = new DirBundleFile(content, strictPath);
} else {
@@ -1344,13 +1397,14 @@
out.writeLong(bundleInfo.getNextGenerationId());
out.writeLong(generation.getGenerationId());
out.writeBoolean(generation.isDirectory());
- out.writeBoolean(generation.isReference());
+ Type contentType = generation.getContentType();
+ out.writeInt(contentType.ordinal());
out.writeBoolean(generation.hasPackageInfo());
- if (bundleInfo.getBundleId() == 0) {
- // just write empty string for system bundle content in this case
+ if (bundleInfo.getBundleId() == 0 || contentType == Type.CONNECT) {
+ // just write empty string for system bundle content and connect content in this case
out.writeUTF(""); //$NON-NLS-1$
} else {
- if (generation.isReference()) {
+ if (contentType == Type.REFERENCE) {
// make reference installs relative to the install path
out.writeUTF(new FilePath(installPath).makeRelative(new FilePath(generation.getContent().getAbsolutePath())));
} else {
@@ -1450,13 +1504,23 @@
int numInfos = in.readInt();
Map<Long, Generation> result = new HashMap<>(numInfos);
List<Generation> generations = new ArrayList<>(numInfos);
+ Type[] contentTypes = Type.values();
for (int i = 0; i < numInfos; i++) {
long infoId = in.readLong();
String infoLocation = ObjectPool.intern(in.readUTF());
long nextGenId = in.readLong();
long generationId = in.readLong();
boolean isDirectory = in.readBoolean();
- boolean isReference = in.readBoolean();
+
+ Type contentType = Type.DEFAULT;
+ if (version >= CONTENT_TYPE_VERSION) {
+ contentType = contentTypes[in.readInt()];
+ } else {
+ if (in.readBoolean()) {
+ contentType = Type.REFERENCE;
+ }
+ }
+
boolean hasPackageInfo = in.readBoolean();
String contentPath = in.readUTF();
long lastModified = in.readLong();
@@ -1473,37 +1537,58 @@
}
boolean isMRJar = (version >= MR_JAR_VERSION) ? in.readBoolean() : false;
- File content;
- if (infoId == 0) {
- content = getSystemContent();
- isDirectory = content != null ? content.isDirectory() : false;
- // Note that we do not do any checking for absolute paths with
- // the system bundle. We always take the content as discovered
- // by getSystemContent()
- } else {
- content = new File(contentPath);
- if (!content.isAbsolute()) {
- // make sure it has the absolute location instead
- if (isReference) {
- // reference installs are relative to the installPath
- content = new File(installPath, contentPath);
- } else {
- // normal installs are relative to the storage area
- content = getFile(contentPath, true);
+ File content = null;
+ if (contentType != Type.CONNECT) {
+ if (infoId == 0) {
+ content = getSystemContent();
+ isDirectory = content != null ? content.isDirectory() : false;
+ // Note that we do not do any checking for absolute paths with
+ // the system bundle. We always take the content as discovered
+ // by getSystemContent()
+ } else {
+ content = new File(contentPath);
+ if (!content.isAbsolute()) {
+ // make sure it has the absolute location instead
+ switch (contentType) {
+ case REFERENCE:
+ // reference installs are relative to the installPath
+ content = new File(installPath, contentPath);
+ break;
+ case DEFAULT:
+ // normal installs are relative to the storage area
+ content = getFile(contentPath, true);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown type: " + contentType); //$NON-NLS-1$
+ }
}
}
}
-
BundleInfo info = new BundleInfo(this, infoId, infoLocation, nextGenId);
- Generation generation = info.restoreGeneration(generationId, content, isDirectory, isReference, hasPackageInfo, cachedHeaders, lastModified, isMRJar);
+ Generation generation = info.restoreGeneration(generationId, content, isDirectory, contentType, hasPackageInfo, cachedHeaders, lastModified, isMRJar);
result.put(infoId, generation);
generations.add(generation);
}
+ connectPersistentBundles(generations);
loadStorageHookData(generations, in);
return result;
}
+ private void connectPersistentBundles(List<Generation> generations) {
+ generations.forEach(g -> {
+ try {
+ if (g.getContentType() == Type.CONNECT) {
+ equinoxContainer.getConnectModules().connect(g.getBundleInfo().getLocation());
+ }
+ } catch (IllegalStateException e) {
+ if (!(e.getCause() instanceof BundleException)) {
+ throw e;
+ }
+ }
+ });
+ }
+
private void loadStorageHookData(List<Generation> generations, DataInputStream in) throws IOException {
List<StorageHookFactory<?, ?, ?>> factories = new ArrayList<>(getConfiguration().getHookRegistry().getStorageHookFactories());
Map<Generation, List<StorageHook<?, ?>>> hookMap = new HashMap<>();
@@ -1695,7 +1780,7 @@
}
if (profileIn == null)
// the profile url is still null then use the min profile the framework can use
- profileIn = findInSystemBundle(systemGeneration, "JavaSE-1.7.profile"); //$NON-NLS-1$
+ profileIn = findInSystemBundle(systemGeneration, "JavaSE-1.8.profile"); //$NON-NLS-1$
if (profileIn != null) {
try {
result.load(new BufferedInputStream(profileIn));
@@ -2217,4 +2302,8 @@
}
return storageStream;
}
+
+ EquinoxContainer getEquinoxContainer() {
+ return equinoxContainer;
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
index 73720b9..aeb4cc5 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
@@ -72,7 +72,7 @@
* Checks if the bundle file is open
* @return true if the bundle file is open and locked
*/
- private boolean lockOpen() {
+ protected boolean lockOpen() {
try {
open(true);
return true;
@@ -98,6 +98,13 @@
}
/**
+ * Unlocks the open lock
+ */
+ protected void releaseOpen() {
+ openLock.unlock();
+ }
+
+ /**
* Opens this bundle file.
* @param keepLock true if the open lock should be retained
* @throws IOException
@@ -162,7 +169,7 @@
}
return getExtractFile(dirName);
} finally {
- openLock.unlock();
+ releaseOpen();
}
}
@@ -219,7 +226,7 @@
generation.getBundleInfo().getStorage().getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "Unable to extract content: " + generation.getRevision() + ": " + entry, e); //$NON-NLS-1$ //$NON-NLS-2$
}
} finally {
- openLock.unlock();
+ releaseOpen();
}
return null;
}
@@ -251,7 +258,7 @@
}
}
} finally {
- openLock.unlock();
+ releaseOpen();
}
return false;
}
@@ -264,7 +271,7 @@
try {
return findEntry(path);
} finally {
- openLock.unlock();
+ releaseOpen();
}
}
@@ -307,7 +314,7 @@
}
return result.size() == 0 ? null : Collections.enumeration(result);
} finally {
- openLock.unlock();
+ releaseOpen();
}
}
@@ -449,7 +456,7 @@
}
return in;
} finally {
- openLock.unlock();
+ releaseOpen();
}
}
@@ -542,7 +549,9 @@
}
private IOException enrichExceptionWithBaseFile(IOException e) {
- return new IOException(getBaseFile().toString(), e);
+ File baseFile = getBaseFile();
+ String extraInfo = baseFile == null ? generation.getBundleInfo().getLocation() : baseFile.toString();
+ return new IOException(extraInfo, e);
}
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
index b9ff45f..1ce4ba3 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
@@ -17,12 +17,13 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import org.eclipse.osgi.storage.ContentProvider;
/**
* InputStream subclass which provides a reference (via File) to the data
* rather than allowing the input stream to be directly read.
*/
-public class ReferenceInputStream extends InputStream {
+public class ReferenceInputStream extends InputStream implements ContentProvider {
private final File reference;
public ReferenceInputStream(File reference) {
@@ -37,6 +38,16 @@
}
public File getReference() {
+ return getContent();
+ }
+
+ @Override
+ public File getContent() {
return reference;
}
+
+ @Override
+ public Type getType() {
+ return Type.REFERENCE;
+ }
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
index 7b08160..7a45b1c 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/BundlePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2004, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -543,7 +543,7 @@
// work our way up the tree...
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
bp = pc.get(requestedName);
if (bp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
index 8a38df0..c7bae50 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2017). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -714,7 +714,7 @@
/* work our way up the tree... */
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
cp = pc.get(requestedName);
if (cp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
index 41e648a..57af872 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2018). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1025,7 +1025,6 @@
/**
* Framework environment property identifying whether the Framework supports
* bootclasspath extension bundles.
- *
* <p>
* If the value of this property is {@code true}, then the Framework
* supports bootclasspath extension bundles. The default value is
@@ -1035,6 +1034,7 @@
* {@code BundleContext.getProperty} method.
*
* @since 1.3
+ * @deprecated As of 1.10.
*/
String SUPPORTS_BOOTCLASSPATH_EXTENSION = "org.osgi.supports.bootclasspath.extension";
@@ -1574,7 +1574,7 @@
String SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
/**
- * Service property identifying the intents that this service implement.
+ * Service property identifying the intents that this service implements.
* This property has a dual purpose:
* <ul>
* <li>A bundle can use this service property to notify the distribution
@@ -1833,8 +1833,8 @@
* Service property identifying the monotonically increasing change count of
* a service.
* <p>
- * A service may optional provide this property to indicate there has been a
- * change in some data provided by the service. The change count must be
+ * A service may provide this property to indicate there has been a change
+ * in some data provided by the service. The change count must be
* incremented with a positive value every time the data provided by the
* service is changed. The service announces the modified change count by
* updating its service properties with the new value for this service
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
index b3072b2..bcff061 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2004, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -148,13 +148,13 @@
/**
* The Framework has stopped and the boot class path has changed.
- *
* <p>
* This event is fired when the Framework has been stopped because of a stop
* operation on the system bundle and a bootclasspath extension bundle has
* been installed or updated. The source of this event is the System Bundle.
*
* @since 1.5
+ * @deprecated As of 1.10.
*/
public final static int STOPPED_BOOTCLASSPATH_MODIFIED = 0x00000100;
@@ -173,9 +173,9 @@
* The Framework has stopped and the framework requires a new class loader
* to restart.
* <p>
- * This event is fired when the Framework has been stopped because of a stop
- * operation on the system bundle and the framework requires a new class
- * loader to be used to restart. For example, if a framework extension
+ * This event is fired when the Framework has been stopped because of a
+ * refresh operation on the system bundle and the framework requires a new
+ * class loader to be used to restart. For example, if a framework extension
* bundle has been refreshed. The source of this event is the System Bundle.
*
* @since 1.9
@@ -244,7 +244,6 @@
* <li>{@link #PACKAGES_REFRESHED}</li>
* <li>{@link #STARTLEVEL_CHANGED}</li>
* <li>{@link #STOPPED}</li>
- * <li>{@link #STOPPED_BOOTCLASSPATH_MODIFIED}</li>
* <li>{@link #STOPPED_UPDATE}</li>
* <li>{@link #WAIT_TIMEDOUT}</li>
* </ul>
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
index 8003880..587b532 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2005, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,27 @@
package org.osgi.framework;
+import static java.util.Objects.requireNonNull;
+
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.ServiceLoader;
+import java.util.Set;
+
import javax.security.auth.x500.X500Principal;
import org.eclipse.osgi.internal.framework.FilterImpl;
-import org.eclipse.osgi.internal.hookregistry.FrameworkUtilHelper;
+import org.osgi.framework.connect.FrameworkUtilHelper;
/**
* Framework Utility class.
@@ -185,60 +196,72 @@
return DNChainMatching.match(matchPattern, dnChain);
}
+ /**
+ * Return a {@code Bundle} for the specified bundle class loader.
+ *
+ * @param bundleClassLoader A bundle class loader.
+ * @return An Optional containing {@code Bundle} for the specified bundle
+ * class loader or an empty Optional if the specified class loader
+ * is not associated with a specific bundle.
+ * @since 1.10
+ */
+ public static Optional<Bundle> getBundle(ClassLoader bundleClassLoader) {
+ requireNonNull(bundleClassLoader);
+ return Optional
+ .ofNullable((bundleClassLoader instanceof BundleReference)
+ ? ((BundleReference) bundleClassLoader).getBundle()
+ : null);
+ }
+
+ /**
+ * Return a {@code Bundle} for the specified bundle class.
+ *
+ * @param classFromBundle A class defined by a bundle.
+ * @return A {@code Bundle} for the specified bundle class or {@code null}
+ * if the specified class was not defined by a bundle.
+ * @since 1.5
+ */
+ public static Bundle getBundle(Class< ? > classFromBundle) {
+ // We use doPriv since the caller may not have permission
+ // to call getClassLoader.
+ Optional<ClassLoader> cl = Optional
+ .ofNullable(AccessController.doPrivileged(
+ (PrivilegedAction<ClassLoader>) () -> classFromBundle
+ .getClassLoader()));
+
+ return cl.flatMap(FrameworkUtil::getBundle)
+ .orElseGet(() -> helpers.stream()
+ .map(helper -> helper.getBundle(classFromBundle))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst()
+ .orElse(null));
+ }
+
private final static List<FrameworkUtilHelper> helpers;
static {
List<FrameworkUtilHelper> l = new ArrayList<>();
try {
- ServiceLoader<FrameworkUtilHelper> helperLoader = AccessController.doPrivileged(new PrivilegedAction<ServiceLoader<FrameworkUtilHelper>>() {
- @Override
- public ServiceLoader<FrameworkUtilHelper> run() {
- return ServiceLoader.load(FrameworkUtilHelper.class, FrameworkUtilHelper.class.getClassLoader());
- }
- });
- for (Iterator<FrameworkUtilHelper> iHelpers = helperLoader.iterator(); iHelpers.hasNext();) {
- l.add(iHelpers.next());
+ ServiceLoader<FrameworkUtilHelper> helperLoader = AccessController
+ .doPrivileged(
+ (PrivilegedAction<ServiceLoader<FrameworkUtilHelper>>) () -> ServiceLoader
+ .load(FrameworkUtilHelper.class,
+ FrameworkUtilHelper.class
+ .getClassLoader()));
+ helperLoader.forEach(l::add);
+ } catch (Throwable error) {
+ // try hard not to fail static <clinit>
+ try {
+ Thread t = Thread.currentThread();
+ t.getUncaughtExceptionHandler().uncaughtException(t, error);
+ } catch (Throwable ignored) {
+ // we ignore this
}
- } catch (Throwable t) {
- // should not fail out of static initializers
- t.printStackTrace();
}
helpers = Collections.unmodifiableList(l);
}
/**
- * Return a {@code Bundle} for the specified bundle class. The returned
- * {@code Bundle} is the bundle associated with the bundle class loader
- * which defined the specified class.
- *
- * @param classFromBundle A class defined by a bundle class loader.
- * @return A {@code Bundle} for the specified bundle class or {@code null}
- * if the specified class was not defined by a bundle class loader.
- * @since 1.5
- */
- public static Bundle getBundle(final Class<?> classFromBundle) {
- // We use doPriv since the caller may not have permission
- // to call getClassLoader.
- Object cl = AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- return classFromBundle.getClassLoader();
- }
- });
-
- if (cl instanceof BundleReference) {
- return ((BundleReference) cl).getBundle();
- }
-
- for (FrameworkUtilHelper helper : helpers) {
- Bundle b = helper.getBundle(classFromBundle);
- if (b != null) {
- return b;
- }
- }
- return null;
- }
-
- /**
* This class contains a method to match a distinguished name (DN) chain
* against and DN chain pattern.
* <p>
@@ -680,4 +703,357 @@
return sb.toString();
}
}
+
+ /**
+ * Return a Map wrapper around a Dictionary.
+ *
+ * @param <K> The type of the key.
+ * @param <V> The type of the value.
+ * @param dictionary The dictionary to wrap.
+ * @return A Map object which wraps the specified dictionary. If the
+ * specified dictionary can be cast to a Map, then the specified
+ * dictionary is returned.
+ * @since 1.10
+ */
+ public static <K, V> Map<K,V> asMap(
+ Dictionary< ? extends K, ? extends V> dictionary) {
+ if (dictionary instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<K,V> coerced = (Map<K,V>) dictionary;
+ return coerced;
+ }
+ return new DictionaryAsMap<>(dictionary);
+ }
+
+ private static class DictionaryAsMap<K, V> extends AbstractMap<K,V> {
+ private final Dictionary<K,V> dict;
+
+ @SuppressWarnings("unchecked")
+ DictionaryAsMap(Dictionary< ? extends K, ? extends V> dict) {
+ this.dict = (Dictionary<K,V>) requireNonNull(dict);
+ }
+
+ Iterator<K> keys() {
+ List<K> keys = new ArrayList<>(dict.size());
+ for (Enumeration<K> e = dict.keys(); e.hasMoreElements();) {
+ keys.add(e.nextElement());
+ }
+ return keys.iterator();
+ }
+
+ @Override
+ public int size() {
+ return dict.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return dict.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ if (key == null) {
+ return false;
+ }
+ return dict.get(key) != null;
+ }
+
+ @Override
+ public V get(Object key) {
+ if (key == null) {
+ return null;
+ }
+ return dict.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return dict.put(
+ requireNonNull(key,
+ "a Dictionary cannot contain a null key"),
+ requireNonNull(value,
+ "a Dictionary cannot contain a null value"));
+ }
+
+ @Override
+ public V remove(Object key) {
+ if (key == null) {
+ return null;
+ }
+ return dict.remove(key);
+ }
+
+ @Override
+ public void clear() {
+ for (Iterator<K> iter = keys(); iter.hasNext();) {
+ dict.remove(iter.next());
+ }
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return new KeySet();
+ }
+
+ @Override
+ public Set<Map.Entry<K,V>> entrySet() {
+ return new EntrySet();
+ }
+
+ @Override
+ public String toString() {
+ return dict.toString();
+ }
+
+ final class KeySet extends AbstractSet<K> {
+ @Override
+ public Iterator<K> iterator() {
+ return new KeyIterator();
+ }
+
+ @Override
+ public int size() {
+ return DictionaryAsMap.this.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return DictionaryAsMap.this.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object key) {
+ return DictionaryAsMap.this.containsKey(key);
+ }
+
+ @Override
+ public boolean remove(Object key) {
+ return DictionaryAsMap.this.remove(key) != null;
+ }
+
+ @Override
+ public void clear() {
+ DictionaryAsMap.this.clear();
+ }
+ }
+
+ final class KeyIterator implements Iterator<K> {
+ private final Iterator<K> keys = DictionaryAsMap.this.keys();
+ private K key = null;
+
+ @Override
+ public boolean hasNext() {
+ return keys.hasNext();
+ }
+
+ @Override
+ public K next() {
+ return key = keys.next();
+ }
+
+ @Override
+ public void remove() {
+ if (key == null) {
+ throw new IllegalStateException();
+ }
+ DictionaryAsMap.this.remove(key);
+ key = null;
+ }
+ }
+
+ final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
+ @Override
+ public Iterator<Map.Entry<K,V>> iterator() {
+ return new EntryIterator();
+ }
+
+ @Override
+ public int size() {
+ return DictionaryAsMap.this.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return DictionaryAsMap.this.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ if (o instanceof Map.Entry) {
+ Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) o;
+ return containsEntry(e);
+ }
+ return false;
+ }
+
+ private boolean containsEntry(Map.Entry< ? , ? > e) {
+ Object key = e.getKey();
+ if (key == null) {
+ return false;
+ }
+ Object value = e.getValue();
+ if (value == null) {
+ return false;
+ }
+ return Objects.equals(DictionaryAsMap.this.get(key), value);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ if (o instanceof Map.Entry) {
+ Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) o;
+ if (containsEntry(e)) {
+ DictionaryAsMap.this.remove(e.getKey());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ DictionaryAsMap.this.clear();
+ }
+ }
+
+ final class EntryIterator implements Iterator<Map.Entry<K,V>> {
+ private final Iterator<K> keys = DictionaryAsMap.this.keys();
+ private K key = null;
+
+ @Override
+ public boolean hasNext() {
+ return keys.hasNext();
+ }
+
+ @Override
+ public Map.Entry<K,V> next() {
+ return new Entry(key = keys.next());
+ }
+
+ @Override
+ public void remove() {
+ if (key == null) {
+ throw new IllegalStateException();
+ }
+ DictionaryAsMap.this.remove(key);
+ key = null;
+ }
+ }
+
+ final class Entry extends SimpleEntry<K,V> {
+ private static final long serialVersionUID = 1L;
+
+ Entry(K key) {
+ super(key, DictionaryAsMap.this.get(key));
+ }
+
+ @Override
+ public V setValue(V value) {
+ DictionaryAsMap.this.put(getKey(), value);
+ return super.setValue(value);
+ }
+ }
+ }
+
+ /**
+ * Return a Dictionary wrapper around a Map.
+ *
+ * @param <K> The type of the key.
+ * @param <V> The type of the value.
+ * @param map The map to wrap.
+ * @return A Dictionary object which wraps the specified map. If the
+ * specified map can be cast to a Dictionary, then the specified map
+ * is returned.
+ * @since 1.10
+ */
+ public static <K, V> Dictionary<K,V> asDictionary(
+ Map< ? extends K, ? extends V> map) {
+ if (map instanceof Dictionary) {
+ @SuppressWarnings("unchecked")
+ Dictionary<K,V> coerced = (Dictionary<K,V>) map;
+ return coerced;
+ }
+ return new MapAsDictionary<>(map);
+ }
+
+ private static class MapAsDictionary<K, V> extends Dictionary<K,V> {
+ private final Map<K,V> map;
+
+ @SuppressWarnings("unchecked")
+ MapAsDictionary(Map< ? extends K, ? extends V> map) {
+ this.map = (Map<K,V>) requireNonNull(map);
+ boolean nullKey;
+ try {
+ nullKey = map.containsKey(null);
+ } catch (NullPointerException e) {
+ nullKey = false; // map does not allow null key
+ }
+ if (nullKey) {
+ throw new NullPointerException(
+ "a Dictionary cannot contain a null key");
+ }
+ boolean nullValue;
+ try {
+ nullValue = map.containsValue(null);
+ } catch (NullPointerException e) {
+ nullValue = false; // map does not allow null value
+ }
+ if (nullValue) {
+ throw new NullPointerException(
+ "a Dictionary cannot contain a null value");
+ }
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public Enumeration<K> keys() {
+ return Collections.enumeration(map.keySet());
+ }
+
+ @Override
+ public Enumeration<V> elements() {
+ return Collections.enumeration(map.values());
+ }
+
+ @Override
+ public V get(Object key) {
+ if (key == null) {
+ return null;
+ }
+ return map.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return map.put(
+ requireNonNull(key,
+ "a Dictionary cannot contain a null key"),
+ requireNonNull(value,
+ "a Dictionary cannot contain a null value"));
+ }
+
+ @Override
+ public V remove(Object key) {
+ if (key == null) {
+ return null;
+ }
+ return map.remove(key);
+ }
+
+ @Override
+ public String toString() {
+ return map.toString();
+ }
+ }
+
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
index 264ccd6..cc8cd62 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/PackagePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2017). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -713,7 +713,7 @@
/* work our way up the tree... */
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
pp = pc.get(requestedName);
if (pp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
index 8db61d0..a6b5252 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServicePermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2017). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -866,7 +866,7 @@
// work our way up the tree...
int last;
int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+ while ((last = requestedName.lastIndexOf('.', offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
sp = pc.get(requestedName);
if (sp != null) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.java
index 1454244..adb91d7 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2017). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +53,8 @@
* @author $Id$
*/
@ProviderType
-public interface ServiceReference<S> extends Comparable<Object> {
+public interface ServiceReference<S>
+ extends Comparable<Object>, BundleReference {
/**
* Returns the property value to which the specified property key is mapped
* in the properties {@code Dictionary} object of the service referenced by
@@ -109,6 +110,7 @@
* already been unregistered.
* @see BundleContext#registerService(String[],Object,Dictionary)
*/
+ @Override
public Bundle getBundle();
/**
@@ -131,14 +133,24 @@
* <p>
* This method performs the following checks:
* <ol>
+ * <li>If the specified bundle is equal to the bundle that registered the
+ * service referenced by this {@code ServiceReference} (registrant bundle)
+ * return {@code true}.</li>
* <li>Get the package name from the specified class name.</li>
- * <li>For the bundle that registered the service referenced by this
- * {@code ServiceReference} (registrant bundle); find the source for the
- * package. If no source is found then return {@code true} if the registrant
- * bundle is equal to the specified bundle; otherwise return {@code false}.</li>
- * <li>If the package source of the registrant bundle is equal to the
- * package source of the specified bundle then return {@code true};
- * otherwise return {@code false}.</li>
+ * <li>For the specified bundle; find the source for the package. If no
+ * source is found then return {@code true} (use of reflection is assumed by
+ * the specified bundle).</li>
+ * <li>For the registrant bundle; find the source for the package. If the
+ * package source is found then return {@code true} if the package source
+ * equals the package source of the specified bundle; otherwise return
+ * {@code false}.</li>
+ * <li>If no package source is found for the registrant bundle then
+ * determine the package source based on the service object. If the service
+ * object is a {@code ServiceFactory} and the factory implementation is not
+ * from the registrant bundle return {@code true}; otherwise attempt to find
+ * the package source based on the service object class. If the package
+ * source is found and is equal to package source of the specified bundle
+ * return {@code true}; otherwise return {@code false}.</li>
* </ol>
*
* @param bundle The {@code Bundle} object to check.
@@ -148,8 +160,8 @@
* bundle use the same source for the package of the specified class
* name. Otherwise {@code false} is returned.
* @throws IllegalArgumentException If the specified {@code Bundle} was not
- * created by the same framework instance as this
- * {@code ServiceReference}.
+ * created by the same framework instance as this
+ * {@code ServiceReference}.
* @since 1.3
*/
public boolean isAssignableTo(Bundle bundle, String className);
@@ -212,4 +224,27 @@
* @since 1.9
*/
public Dictionary<String,Object> getProperties();
+
+ /**
+ * Adapt this {@code ServiceReference} object to the specified type.
+ * <p>
+ * Adapting this {@code ServiceReference} object to the specified type may
+ * require certain checks, including security checks, to succeed. If a check
+ * does not succeed, then this {@code ServiceReference} object cannot be
+ * adapted and {@code null} is returned.
+ *
+ * @param <A> The type to which this {@code ServiceReference} object is to
+ * be adapted.
+ * @param type Class object for the type to which this
+ * {@code ServiceReference} object is to be adapted.
+ * @return The object, of the specified type, to which this
+ * {@code ServiceReference} object has been adapted or {@code null}
+ * if this {@code ServiceReference} object cannot be adapted to the
+ * specified type.
+ * @throws SecurityException If the caller does not have the appropriate
+ * {@code AdaptPermission[type,this,ADAPT]}, and the Java
+ * Runtime Environment supports permissions.
+ * @since 1.10
+ */
+ <A> A adapt(Class<A> type);
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java
new file mode 100644
index 0000000..9e455f9
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectContent.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.framework.connect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Optional;
+
+import org.osgi.annotation.versioning.ConsumerType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevisions;
+
+/**
+ * A {@code ConnectContent} provides a {@link Framework} instance access to the
+ * content of a {@link ConnectModule}.
+ * <p>
+ * A framework may {@link #open() open} and {@link #close() close} the content
+ * for a {@link ConnectModule} multiple times while the {@code ConnectContent}
+ * is in use by the framework. The framework must close the
+ * {@code ConnectContent} once the {@code ConnectContent} is no longer used as
+ * the content of a current bundle revision or an in use bundle revision.
+ * <p>
+ * An entry in a {@code ConnectContent} is identified by a path name that is a
+ * solidus (<code>'/' \u002F</code>) separated path. A {@code ConnectContent}
+ * may treat directories as entries. A directory entry path name will end with a
+ * solidus. A directory entry may be located using a path name that omits the
+ * trailing solidus.
+ *
+ * @see BundleRevisions
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ConsumerType
+public interface ConnectContent {
+ /**
+ * The {@code osgi.identity}
+ * {@link IdentityNamespace#CAPABILITY_TAGS_ATTRIBUTE tags} attribute value
+ * used by the framework to tag connect bundle revisions.
+ */
+ String TAG_OSGI_CONNECT = "osgi.connect";
+
+ /**
+ * Returns the Manifest headers and values of this {@code ConnectContent}.
+ *
+ * @return An {@code Optional} containing the Manifest headers and values
+ * for this {@code ConnectContent}, or an empty {@code Optional} if
+ * the framework should handle parsing the Manifest of the content
+ * itself.
+ * @throws IllegalStateException If this {@code ConnectContent} has been
+ * closed.
+ */
+ Optional<Map<String,String>> getHeaders();
+
+ /**
+ * Returns the entry names available in this {@code ConnectContent}.
+ *
+ * @return An {@code Iterable} which can supply the available entry names.
+ * @throws IOException If an error occurs reading this
+ * {@code ConnectContent}.
+ * @throws IllegalStateException If this {@code ConnectContent} has been
+ * closed.
+ */
+ Iterable<String> getEntries() throws IOException;
+
+ /**
+ * Returns the {@link ConnectEntry} for the specified path name in this
+ * content.
+ * <p>
+ * The {@link Optional#empty() empty} value is returned if an entry with the
+ * specified path name does not exist. The path must not start with a
+ * "/" and is relative to the root of this content. A connect
+ * entry for a directory will have a path name that ends with a slash ('/').
+ *
+ * @param path The path name of the entry.
+ * @return An {@code Optional} containing the {@link ConnectEntry} for the
+ * specified path, or an empty {@code Optional} if no entry for
+ * specified path can be found.
+ * @throws IllegalStateException If this {@code ConnectContent} has been
+ * closed.
+ */
+ Optional<ConnectEntry> getEntry(String path);
+
+ /**
+ * Returns a class loader for this {@code ConnectContent}.
+ * <p>
+ * This method is called by the framework for {@link Bundle#RESOLVED
+ * resolved} bundles only and will be called at most once while a bundle is
+ * resolved. If a bundle associated with a {@link ConnectModule} is
+ * refreshed and resolved again, the framework will ask the
+ * {@code ConnectContent} for the class loader again. This allows for a
+ * {@code ConnectContent} to reuse or create a new class loader each time
+ * the bundle revision is resolved.
+ *
+ * @return An {@code Optional} containing the class loader for this
+ * {@code ConnectContent}, or an empty {@code Optional} if framework
+ * should handle creating a class loader for the bundle revision
+ * associated with this {@code ConnectContent}.
+ * @throws IllegalStateException If this {@code ConnectContent} has been
+ * closed.
+ */
+ Optional<ClassLoader> getClassLoader();
+
+ /**
+ * Opens this {@code ConnectContent}.
+ * <p>
+ * The framework will open the content when it needs to access the content
+ * for a bundle revision associated with this {@code ConnectContent}. The
+ * framework may defer calling this method until requests to access the
+ * bundle revision content are made.
+ *
+ * @throws IOException If an error occurred opening this
+ * {@code ConnectContent}.
+ */
+ void open() throws IOException;
+
+ /**
+ * Closes this {@code ConnectContent}.
+ *
+ * @throws IOException If an error occurred closing this
+ * {@code ConnectContent}.
+ */
+ void close() throws IOException;
+
+ /**
+ * Represents the entry of a {@code ConnectContent}.
+ */
+ @ConsumerType
+ public interface ConnectEntry {
+ /**
+ * Returns the path name of this entry.
+ *
+ * @return The path name of this entry.
+ */
+ String getName();
+
+ /**
+ * Returns the content length of this entry.
+ *
+ * @return The content length of the entry, or {@code -1} if the content
+ * length is not known.
+ */
+ public long getContentLength();
+
+ /**
+ * Returns the last modification time of this entry.
+ *
+ * @return The last modification time of this entry measured in
+ * milliseconds since the epoch (00:00:00 GMT, January 1, 1970).
+ */
+ public long getLastModified();
+
+ /**
+ * Returns the content of this entry.
+ *
+ * @return The content of this entry.
+ * @throws IOException If an error occurs reading the content.
+ */
+ default byte[] getBytes() throws IOException {
+ long longLength = getContentLength();
+ if (longLength > Integer.MAX_VALUE - 8) {
+ throw new IOException(
+ "Entry is to big to fit into a byte[]: " + getName());
+ }
+
+ try (InputStream in = getInputStream()) {
+ int length = (int) longLength;
+ if (length > 0) {
+ int bytesread = 0;
+ byte[] result = new byte[length];
+ int readcount = 0;
+ while (bytesread < length) {
+ readcount = in.read(result, bytesread,
+ length - bytesread);
+ bytesread += readcount;
+ if (readcount <= 0) {
+ break;
+ }
+ }
+ return result;
+ } else {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ int nRead;
+ byte[] data = new byte[1024];
+ while ((nRead = in.read(data, 0, data.length)) > 0) {
+ buffer.write(data, 0, nRead);
+ }
+ buffer.flush();
+ return buffer.toByteArray();
+ }
+ }
+ }
+
+ /**
+ * Returns an input stream for the content of this entry.
+ *
+ * @return An input stream for the content of this entry.
+ * @throws IOException If an error occurs reading the content.
+ */
+ InputStream getInputStream() throws IOException;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFrameworkFactory.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFrameworkFactory.java
new file mode 100644
index 0000000..fee4e88
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectFrameworkFactory.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.framework.connect;
+
+import java.util.Map;
+
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+
+/**
+ * A factory for creating {@link Framework} instances.
+ * <p>
+ * If a framework supports {@link ModuleConnector}, then the implementation jar
+ * must contain the following resource:
+ *
+ * <pre>
+ * /META-INF/services/org.osgi.framework.connect.ConnectFrameworkFactory
+ * </pre>
+ *
+ * This UTF-8 encoded resource must contain the name of the framework
+ * implementation's ConnectFrameworkFactory implementation class. Space and tab
+ * characters, including blank lines, in the resource must be ignored. The
+ * number sign ({@code '#'} \u0023) and all characters following it on each
+ * line are a comment and must be ignored.
+ * <p>
+ * Launchers can find the name of the ConnectFrameworkFactory implementation
+ * class in the resource and then load and construct a ConnectFrameworkFactory
+ * object for the framework implementation. The ConnectFrameworkFactory
+ * implementation class must have a public, no-argument constructor. Java™
+ * SE 6 introduced the {@code ServiceLoader} class which can create a
+ * ConnectFrameworkFactory instance from the resource.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface ConnectFrameworkFactory {
+ /**
+ * Create a new {@link Framework} instance using the specified
+ * {@link ModuleConnector module connector}.
+ *
+ * @param configuration The framework properties to configure the new
+ * framework instance. If framework properties are not provided
+ * by the configuration argument, the created framework instance
+ * must use some reasonable default configuration appropriate for
+ * the current VM. For example, the system packages for the
+ * current execution environment should be properly exported. The
+ * specified configuration argument may be {@code null}. The
+ * created framework instance must copy any information needed
+ * from the specified configuration argument since the
+ * configuration argument can be changed after the framework
+ * instance has been created.
+ * @param moduleConnector The module connector that the new framework
+ * instance will use. The specified module connector argument may
+ * be {@code null}.
+ * @return A new, configured {@link Framework} instance. The framework
+ * instance must be in the {@link Bundle#INSTALLED} state.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}, and the Java Runtime Environment
+ * supports permissions.
+ * @see ModuleConnector
+ */
+ Framework newFramework(Map<String,String> configuration,
+ ModuleConnector moduleConnector);
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java
new file mode 100644
index 0000000..d81245b
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ConnectModule.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.framework.connect;
+
+import java.io.IOException;
+
+import org.osgi.annotation.versioning.ConsumerType;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * A {@code ConnectModule} is used by a {@link Framework} instance to access the
+ * content of the connected bundle.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ConsumerType
+public interface ConnectModule {
+ /**
+ * Returns the current content of this connect module.
+ * <p>
+ * The framework must call this method when it needs to access the content
+ * for the current {@link BundleRevision bundle revision} of this
+ * {@code ConnectModule}. The framework may defer opening the returned
+ * {@link ConnectContent} until requests to access the bundle revision
+ * content are made.
+ *
+ * @return The current {@link ConnectContent} of this {@code ConnectModule}.
+ * @throws IOException If an error occurred getting the content.
+ * @see ModuleConnector#connect(String)
+ */
+ ConnectContent getContent() throws IOException;
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java
new file mode 100644
index 0000000..f7b54ab
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/FrameworkUtilHelper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.framework.connect;
+
+import java.util.Optional;
+
+import org.osgi.annotation.versioning.ConsumerType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * A helper for the {@link FrameworkUtil} class.
+ * <p>
+ * This helper provides alternative implementations for methods on
+ * {@link FrameworkUtil}.
+ */
+@ConsumerType
+public interface FrameworkUtilHelper {
+ /**
+ * Returns the {@link Bundle} associated with the specified class.
+ * <p>
+ * This helper method is called by {@link FrameworkUtil#getBundle(Class)} if
+ * the standard implementation of {@link FrameworkUtil} is unable to find
+ * the bundle.
+ *
+ * @param classFromBundle A class associated with a bundle.
+ * @return An {@code Optional} containing the {@link Bundle} for the
+ * specified class, or an empty {@code Optional} if the specified
+ * class is not from a bundle.
+ */
+ default Optional<Bundle> getBundle(Class< ? > classFromBundle) {
+ return Optional.empty();
+ }
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ModuleConnector.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ModuleConnector.java
new file mode 100644
index 0000000..5ee358a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/ModuleConnector.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.framework.connect;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Optional;
+
+import org.osgi.annotation.versioning.ConsumerType;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.launch.Framework;
+
+/**
+ * A {@code ModuleConnector} provides connections to instances of
+ * {@link ConnectModule} that are used by a {@link Framework} instance to
+ * connect installed bundles locations with content provided by the
+ * {@code ModuleConnector}.
+ * <p>
+ * This allows a {@code ModuleConnector} to provide content and classes for a
+ * connected bundle installed in the {@code Framework}. A
+ * {@code ModuleConnector} is provided when
+ * {@link ConnectFrameworkFactory#newFramework(Map, ModuleConnector) creating} a
+ * framework instance. Because a {@code ModuleConnector} instance can
+ * participate in the initialization of the {@code Framework} and the life cycle
+ * of a {@code Framework} instance the {@code ModuleConnector} instance should
+ * only be used with a single {@code Framework} instance at a time.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ConsumerType
+public interface ModuleConnector {
+
+ /**
+ * Initializes this {@code ModuleConnector} with the
+ * {@link Constants#FRAMEWORK_STORAGE framework persistent storage} file and
+ * framework properties configured for a {@link Framework} instance.
+ * <p>
+ * This method is called once by a {@link Framework} instance and is called
+ * before any other methods on this module connector are called.
+ *
+ * @param storage The persistent storage area used by the {@link Framework}
+ * or {@code null} if the platform does not have file system
+ * support.
+ * @param configuration An unmodifiable map of framework configuration
+ * properties that were used to configure the new framework
+ * instance.
+ */
+ void initialize(File storage, Map<String,String> configuration);
+
+ /**
+ * Connects a bundle location with a {@link ConnectModule}.
+ * <p>
+ * When the result is empty, then the framework must handle reading the
+ * content of the bundle itself. Otherwise, the returned
+ * {@link ConnectModule} must be used by the framework to access the content
+ * of the bundle.
+ *
+ * @param location The bundle location used to install a bundle.
+ * @return An {@code Optional} containing the {@link ConnectModule} for the
+ * specified bundle location, or an empty {@code Optional} if the
+ * framework must handle reading the content of the bundle itself.
+ * @throws BundleException If the location cannot be handled.
+ */
+ Optional<ConnectModule> connect(String location) throws BundleException;
+
+ /**
+ * Creates a new activator for this {@code ModuleConnector}.
+ * <p>
+ * This method is called by the framework during framework
+ * {@link Framework#init(FrameworkListener...) initialization}. Returning an
+ * activator allows this {@code ModuleConnector} to participate in the
+ * framework life cycle. If an activator is returned:
+ * <ul>
+ * <li>The framework will call the activator's
+ * {@link BundleActivator#start(BundleContext) start} method prior to
+ * activating any extension bundles.</li>
+ * <li>The framework will call the activator's
+ * {@link BundleActivator#stop(BundleContext) stop} method after
+ * deactivating any extension bundles.</li>
+ * </ul>
+ *
+ * @return An {@code Optional} containing a new {@link BundleActivator} for
+ * this {@code ModuleConnector}, or an empty {@code Optional} if no
+ * {@link BundleActivator} is necessary.
+ */
+ Optional<BundleActivator> newBundleActivator();
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java
new file mode 100644
index 0000000..b7344ca
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/connect/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2019, 2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+/**
+ * Framework Connect Package Version 1.0.
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.framework.connect; version="[1.0,2.0)"}
+ *
+ * @author $Id$
+ */
+
+@Version("1.0")
+package org.osgi.framework.connect;
+
+import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/dto/ServiceReferenceDTO.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/dto/ServiceReferenceDTO.java
index 87265de..8ac26a2 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/dto/ServiceReferenceDTO.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/dto/ServiceReferenceDTO.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,16 +17,17 @@
package org.osgi.framework.dto;
import java.util.Map;
+
import org.osgi.dto.DTO;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
/**
* Data Transfer Object for a ServiceReference.
- *
* <p>
* {@code ServiceReferenceDTO}s for all registered services can be obtained from
- * a {@link FrameworkDTO}. A started Bundle can be adapted to provide a
+ * a {@link FrameworkDTO}. A {@link ServiceReference} can be adapted to a
+ * {@code ServiceReferenceDTO}. A started Bundle can be adapted to provide a
* {@code ServiceReferenceDTO[]} of the services registered by the Bundle. A
* {@code ServiceReferenceDTO} obtained from a framework must convert service
* property values which are not valid value types for DTOs to type
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingException.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingException.java
index 7575fc1..29ebe64 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingException.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,7 @@
/**
* A weaving exception used to indicate that the class load should be failed but
- * the weaving hook must not be blacklisted by the framework.
- *
+ * the weaving hook must not be deny listed by the framework.
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingHook.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingHook.java
index 8d99df5..e5b5412 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingHook.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WeavingHook.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,24 +42,23 @@
public interface WeavingHook {
/**
* Weaving hook method.
- *
+ * <p>
* This method can modify the specified woven class object to weave the
* class being defined.
- *
* <p>
* If this method throws any exception, the framework must log the exception
* and fail the class load in progress. This weaving hook service must be
- * blacklisted by the framework and must not be called again. The
- * blacklisting of this weaving hook service must expire when this weaving
- * hook service is unregistered. However, this method can throw a
+ * deny listed by the framework and must not be called again. The deny
+ * listing of this weaving hook service must expire when this weaving hook
+ * service is unregistered. However, this method can throw a
* {@link WeavingException} to deliberately fail the class load in progress
- * without being blacklisted by the framework.
+ * without being deny listed by the framework.
*
* @param wovenClass The {@link WovenClass} object that represents the data
- * that will be used to define the class.
+ * that will be used to define the class.
* @throws WeavingException If this weaving hook wants to deliberately fail
- * the class load in progress without being blacklisted by the
- * framework
+ * the class load in progress without being deny listed by the
+ * framework
*/
public void weave(WovenClass wovenClass);
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
index 7fa6797..bf960bd 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2008, 2018). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
+
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
@@ -117,37 +118,33 @@
* A Framework Event is returned to indicate why this Framework has stopped.
*
* @param timeout Maximum number of milliseconds to wait until this
- * Framework has completely stopped. A value of zero will wait
- * indefinitely.
+ * Framework has completely stopped. A value of zero will wait
+ * indefinitely.
* @return A Framework Event indicating the reason this method returned. The
* following {@code FrameworkEvent} types may be returned by this
* method.
* <ul>
* <li>{@link FrameworkEvent#STOPPED STOPPED} - This Framework has
- * been stopped. </li>
- *
+ * been stopped.</li>
* <li>{@link FrameworkEvent#STOPPED_UPDATE STOPPED_UPDATE} - This
* Framework has been updated which has shutdown and will now
* restart.</li>
- *
- * <li> {@link FrameworkEvent#STOPPED_BOOTCLASSPATH_MODIFIED
- * STOPPED_BOOTCLASSPATH_MODIFIED} - This Framework has been stopped
- * and a bootclasspath extension bundle has been installed or
- * updated. The VM must be restarted in order for the changed boot
- * class path to take effect. </li>
- *
+ * <li>{@link FrameworkEvent#STOPPED_SYSTEM_REFRESHED
+ * STOPPED_SYSTEM_REFRESHED} - The Framework has been stopped
+ * because of a refresh operation on the system bundle. A new class
+ * loader must be used to restart the Framework.</li>
* <li>{@link FrameworkEvent#ERROR ERROR} - The Framework
* encountered an error while shutting down or an error has occurred
- * which forced the framework to shutdown. </li>
- *
- * <li> {@link FrameworkEvent#WAIT_TIMEDOUT WAIT_TIMEDOUT} - This
+ * which forced the framework to shutdown.</li>
+ * <li>{@link FrameworkEvent#WAIT_TIMEDOUT WAIT_TIMEDOUT} - This
* method has timed out and returned before this Framework has
* stopped.</li>
* </ul>
* @throws InterruptedException If another thread interrupted the current
- * thread before or while the current thread was waiting for this
- * Framework to completely stop. The <i>interrupted status</i> of
- * the current thread is cleared when this exception is thrown.
+ * thread before or while the current thread was waiting for
+ * this Framework to completely stop. The <i>interrupted
+ * status</i> of the current thread is cleared when this
+ * exception is thrown.
* @throws IllegalArgumentException If the value of timeout is negative.
*/
FrameworkEvent waitForStop(long timeout) throws InterruptedException;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
index c1647bc..ecb53ee 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/FrameworkFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.osgi.framework.launch;
import java.util.Map;
+
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Bundle;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
index db5e926..70417d3 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2014). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
index 9f789ca..79484b4 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/HostNamespace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,13 +54,13 @@
* </ul>
*
* <p>
- * A non-fragment resource with the with the
- * {@link IdentityNamespace#TYPE_BUNDLE osgi.bundle} type
- * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} provides zero or
- * one<sup>†</sup> host capabilities. A fragment resource with the
- * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
- * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
- * a host capability and must declare exactly one host requirement.
+ * A non-fragment resource with the {@link IdentityNamespace#TYPE_BUNDLE
+ * osgi.bundle} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} provides zero or one<sup>†</sup> host capabilities. A
+ * fragment resource with the {@link IdentityNamespace#TYPE_FRAGMENT
+ * osgi.fragment} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} must not declare a host capability and must declare exactly one
+ * host requirement.
* <p>
* † A resource with no bundle symbolic name must not provide a host
* capability.
@@ -135,7 +135,6 @@
* fragment. The default value is {@link #EXTENSION_FRAMEWORK framework}.
*
* @see #EXTENSION_FRAMEWORK
- * @see #EXTENSION_BOOTCLASSPATH
*/
public final static String REQUIREMENT_EXTENSION_DIRECTIVE = "extension";
@@ -153,6 +152,7 @@
* loaded by the boot class loader.
*
* @see #REQUIREMENT_EXTENSION_DIRECTIVE
+ * @deprecated As of 1.2.
*/
public final static String EXTENSION_BOOTCLASSPATH = "bootclasspath";
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/IdentityNamespace.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/IdentityNamespace.java
index 7bc7a11..d2357fa 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/IdentityNamespace.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/IdentityNamespace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -105,6 +105,16 @@
public static final String TYPE_UNKNOWN = "unknown";
/**
+ * The attribute value that contains tags for the resource. A tag is used to
+ * identify an aspect of the resource that is not otherwise expressed by the
+ * capabilities of the resource. The value of this attribute must be of type
+ * {@code List<String>}.
+ *
+ * @since 1.2
+ */
+ public static final String CAPABILITY_TAGS_ATTRIBUTE = "tags";
+
+ /**
* The capability attribute that contains a human readable copyright notice
* for the resource. See the {@code Bundle-Copyright} manifest header.
*/
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/NativeNamespace.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/NativeNamespace.java
index fc91420..f252fb2 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/NativeNamespace.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/NativeNamespace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@
* The capability attribute contains alias values of the
* {@link Constants#FRAMEWORK_OS_NAME org.osgi.framework.os.name} launching
* property value according to the
- * <a href="https://www.osgi.org/developer/specifications/reference/">OSGi
+ * <a href="https://docs.osgi.org/reference/">OSGi
* Specification References</a>. The value of this attribute must be of type
* {@code List<String>}.
*/
@@ -62,7 +62,7 @@
* The capability attribute contains alias values of the
* {@link Constants#FRAMEWORK_PROCESSOR org.osgi.framework.processor}
* launching property value according to the
- * <a href="https://www.osgi.org/developer/specifications/reference/">OSGi
+ * <a href="https://docs.osgi.org/reference/">OSGi
* Specification References</a>. The value of this attribute must be of type
* {@code List<String>}.
*/
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/package-info.java
index e89f34a..43f3804 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/namespace/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
*/
/**
- * Namespace Package Version 1.1.
+ * Namespace Package Version 1.2.
*
* <p>
* Bundles should not need to import this package at runtime since all
@@ -25,7 +25,7 @@
* @author $Id$
*/
-@Version("1.1")
+@Version("1.2")
package org.osgi.framework.namespace;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
index 818d4ae..5b79565 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,19 +15,19 @@
*/
/**
- * Framework Package Version 1.9.
+ * Framework Package Version 1.10.
* <p>
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest.
* <p>
* Example import for consumers using the API in this package:
* <p>
- * {@code Import-Package: org.osgi.framework; version="[1.9,2.0)"}
+ * {@code Import-Package: org.osgi.framework; version="[1.10,2.0)"}
*
* @author $Id$
*/
-@Version("1.9")
+@Version("1.10")
package org.osgi.framework;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/Condition.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/Condition.java
new file mode 100644
index 0000000..9736e5e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/Condition.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) OSGi Alliance (2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.osgi.service.condition;
+
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Condition Service interface.
+ * <p>
+ * In dynamic systems, such as OSGi, one of the more challenging problems can be
+ * to define when a system or part of it is ready to do work. The answer can
+ * change depending on the individual perspective. The developer of a web server
+ * might say, the system is ready when the server starts listening on port 80.
+ * An application developer however would define the system as ready when the
+ * database connection is up and all servlets are registered. Taking the
+ * application developers view, the web server should start listening on port 80
+ * when the application is ready and not beforehand.
+ * <p>
+ * The {@code Condition} service interface is a marker interface designed to
+ * address this issue. Its role is to provide a dependency that can be tracked.
+ * It acts as a defined signal to other services.
+ * <p>
+ * A {@code Condition} service must be registered with the
+ * {@link Condition#CONDITION_ID} service property.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ConsumerType
+public interface Condition {
+
+ /**
+ * Service property identifying a condition's unique identifier.
+ * <p>
+ * Since a {@code Condition} service can potentially describe more then one
+ * condition, the type of this service property is {@code String+}.
+ */
+ String CONDITION_ID = "osgi.condition.id";
+
+ /**
+ * The unique identifier for the default True condition.
+ * <p>
+ * The default True condition is registered by the framework during
+ * framework initialization and therefore can always be relied upon.
+ *
+ * @see Condition#CONDITION_ID
+ */
+ String CONDITION_ID_TRUE = "true";
+
+ /**
+ * A condition instance that can be used to register {@code Condition}
+ * services.
+ * <p>
+ * This can be helpful to avoid a bundle having to implement this interface
+ * to register a {@code Condition} service
+ */
+ Condition INSTANCE = new ConditionImpl();
+}
+
+final class ConditionImpl implements Condition {
+ ConditionImpl() {
+ }
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/package-info.java
new file mode 100644
index 0000000..52df94e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/condition/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) OSGi Alliance (2020). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+/**
+ * Condition Service Package Version 1.0.
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.condition; version="[1.0,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.condition; version="[1.0,1.1)"}
+ *
+ * @author $Id$
+ */
+
+@Version("1.0")
+package org.osgi.service.condition;
+
+import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/LogService.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/LogService.java
index 55d1069..b5b08d7 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/LogService.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/LogService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,9 +75,11 @@
* The {@code ServiceReference} field and the {@code Throwable} field of the
* {@code LogEntry} object will be set to {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -105,9 +107,11 @@
* The {@code ServiceReference} field of the {@code LogEntry} object will be
* set to {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -138,9 +142,11 @@
* The {@code Throwable} field of the {@code LogEntry} will be set to
* {@code null}.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
@@ -168,9 +174,11 @@
* Logs a message with an exception associated and a
* {@code ServiceReference} object.
* <p>
- * This method will log to the {@link Logger} named {@code "LogService"} for
- * the bundle. The specified level is mapped to a {@link LogLevel} as
- * follows:
+ * This method will log to the bundle's {@link Logger} named
+ * {@code "LogService.<bsn>"} where {@code <bsn>} is the Bundle Symbolic
+ * Name of the bundle.
+ * <p>
+ * The specified level is mapped to a {@link LogLevel} as follows:
* <ul>
* <li>{@link #LOG_ERROR} - {@link LogLevel#ERROR}</li>
* <li>{@link #LOG_WARNING} - {@link LogLevel#WARN}</li>
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/package-info.java
index 81c287a..b053188 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/log/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010, 2016). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2020). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
*/
/**
- * Log Service Package Version 1.4.
+ * Log Service Package Version 1.5.
* <p>
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
@@ -24,15 +24,15 @@
* <p>
* Example import for consumers using the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.log; version="[1.4,2.0)"}
+ * {@code Import-Package: org.osgi.service.log; version="[1.5,2.0)"}
* <p>
* Example import for providers implementing the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.log; version="[1.4,1.5)"}
+ * {@code Import-Package: org.osgi.service.log; version="[1.5,1.6)"}
*
* @author $Id$
*/
-@Version("1.4")
+@Version("1.5")
package org.osgi.service.log;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
index 86bff00..e4011e1 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2006, 2017). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2006, 2019). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-// This document is an experimental draft to enable interoperability
-// between bundle repositories. There is currently no commitment to
-// turn this draft into an official specification.
-
package org.osgi.service.resolver;
import java.util.List;
diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml
index 74fdea8..8fcf699 100644
--- a/bundles/org.eclipse.osgi/pom.xml
+++ b/bundles/org.eclipse.osgi/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
- <version>3.15.300-SNAPSHOT</version>
+ <version>3.16.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/bundles/org.eclipse.osgi/supplement/.classpath b/bundles/org.eclipse.osgi/supplement/.classpath
index 098194c..eca7bdb 100644
--- a/bundles/org.eclipse.osgi/supplement/.classpath
+++ b/bundles/org.eclipse.osgi/supplement/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
diff --git a/bundles/org.eclipse.osgi/supplement/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.osgi/supplement/.settings/org.eclipse.jdt.core.prefs
index e88e78e..ccae001 100644
--- a/bundles/org.eclipse.osgi/supplement/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.osgi/supplement/.settings/org.eclipse.jdt.core.prefs
@@ -7,9 +7,9 @@
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -70,23 +70,27 @@
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
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_bitwise_operator=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_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=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_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
@@ -156,11 +160,12 @@
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_additive_operator=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_bitwise_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
@@ -190,6 +195,8 @@
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_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=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
@@ -213,12 +220,16 @@
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_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=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_bitwise_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
@@ -264,6 +275,8 @@
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_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=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
@@ -299,8 +312,11 @@
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_relational_operator=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_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=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
@@ -323,6 +339,10 @@
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
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_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
index caa323e..de14a4b 100644
--- a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.supplement
-Bundle-Version: 1.9.300.qualifier
+Bundle-Version: 1.10.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.equinox.log;version="1.1",
@@ -18,7 +18,7 @@
org.eclipse.osgi.service.urlconversion;version="1.0",
org.eclipse.osgi.storagemanager;version="1.0",
org.eclipse.osgi.util;version="1.1"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework,
org.osgi.framework.hooks.resolver,
org.osgi.resource,
diff --git a/bundles/org.eclipse.osgi/supplement/pom.xml b/bundles/org.eclipse.osgi/supplement/pom.xml
index 6a0b34f..8901111 100644
--- a/bundles/org.eclipse.osgi/supplement/pom.xml
+++ b/bundles/org.eclipse.osgi/supplement/pom.xml
@@ -21,7 +21,7 @@
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.supplement</artifactId>
- <version>1.9.300-SNAPSHOT</version>
+ <version>1.10.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>