OpenSplice Java 5 DCPS  v6.x
OpenSplice Java 5 OpenSplice Data Distribution Service Data-Centric Publish-Subscribe API
ServiceEnvironment.java
Go to the documentation of this file.
1 /* Copyright 2010, Object Management Group, Inc.
2  * Copyright 2010, PrismTech, Inc.
3  * Copyright 2010, Real-Time Innovations, Inc.
4  * All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package org.omg.dds.core;
20 
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.concurrent.TimeUnit;
26 
28 import org.omg.dds.core.status.Status;
30 import org.omg.dds.type.TypeSupport;
35 
36 
45 public abstract class ServiceEnvironment implements DDSObject {
46  // -----------------------------------------------------------------------
47  // Public Fields
48  // -----------------------------------------------------------------------
49 
50  public static final String IMPLEMENTATION_CLASS_NAME_PROPERTY =
51  "org.omg.dds.serviceClassName";
52 
53 
54 
55  // -----------------------------------------------------------------------
56  // Private Fields
57  // -----------------------------------------------------------------------
58 
59  private static final String ERROR_STRING =
60  "Unable to load OMG DDS implementation. ";
61 
62 
63 
64  // -----------------------------------------------------------------------
65  // Object Life Cycle
66  // -----------------------------------------------------------------------
67 
80  ClassLoader classLoader)
81  {
82  return createInstance(
83  IMPLEMENTATION_CLASS_NAME_PROPERTY,
84  null,
85  classLoader);
86  }
87 
88 
157  String implClassNameProperty,
158  Map<String, Object> environment,
159  ClassLoader classLoader)
160  {
161  // --- Get implementation class name --- //
162  /* System.getProperty checks the implClassNameProperty argument as
163  * described in the specification for this method and throws
164  * NullPointerException or IllegalArgumentException if necessary.
165  */
166  String className = System.getProperty(implClassNameProperty);
167  if (className == null || className.length() == 0) {
168  // no implementation class name specified
170  ERROR_STRING + "Please set " +
171  implClassNameProperty + " property.");
172  }
173 
174  try {
175  // --- Load implementation class --- //
176  if (classLoader == null) {
177  classLoader = getDefaultClassLoader();
178  }
179  assert classLoader != null;
180  /* IMPORTANT: Load class with ClassLoader.loadClass, not with
181  * Class.forName. The latter provides insufficient control over
182  * the class loader used and also caches class references in
183  * undesirable ways, both of which can cause problems in
184  * container environments such as OSGi.
185  */
186  Class<?> ctxClass = classLoader.loadClass(className);
187 
188  // --- Instantiate new object --- //
189  try {
190  // First, try a constructor that will accept the environment.
191  Constructor<?> ctor = ctxClass.getConstructor(Map.class);
192  return (ServiceEnvironment) ctor.newInstance(environment);
193  } catch (NoSuchMethodException nsmx) {
194  /* No Map constructor found; try a no-argument constructor
195  * instead.
196  *
197  * Get the constructor and call it explicitly rather than
198  * calling Class.newInstance(). The latter propagates all
199  * exceptions, even checked ones, complicating error handling
200  * for us and the user.
201  */
202  Constructor<?> ctor = ctxClass.getConstructor(
203  (Class<?>[]) null);
204  return (ServiceEnvironment) ctor.newInstance((Object[]) null);
205  }
206 
207  // --- Initialization problems --- //
208  } catch (ExceptionInInitializerError initx) {
209  // Presumably thrown by ClassLoader.loadClass, but not documented.
210  // Thrown by Constructor.newInstance.
212  ERROR_STRING + "Error during static initialization.",
213  initx.getCause());
214  } catch (InvocationTargetException itx) {
215  // Thrown by Constructor.newInstance
217  ERROR_STRING + "Error during object initialization.",
218  itx.getCause());
219 
220  // --- Configuration problems --- //
221  } catch (ClassNotFoundException cnfx) {
222  // Thrown by ClassLoader.loadClass.
224  ERROR_STRING + className + " was not found.",
225  cnfx);
226  } catch (LinkageError linkx) {
227  // Presumably thrown by ClassLoader.loadClass, but not documented.
229  ERROR_STRING + className + " could not be loaded.",
230  linkx);
231  } catch (NoSuchMethodException nsmx) {
232  // Thrown by Class.getConstructor: no no-argument constructor
234  ERROR_STRING + className +
235  " has no appropriate constructor.",
236  nsmx);
237  } catch (IllegalAccessException iax) {
238  // Thrown by Constructor.newInstance
240  ERROR_STRING + className +
241  " has no appropriate constructor.",
242  iax);
243  } catch (InstantiationException ix) {
244  // Thrown by Constructor.newInstance
246  ERROR_STRING + className + " could not be instantiated.",
247  ix);
248  } catch (SecurityException sx) {
249  // Thrown by Class.getConstructor.
251  ERROR_STRING + "Prevented by security manager.", sx);
252  } catch (ClassCastException ccx) {
253  // Thrown by type cast
255  ERROR_STRING + className +
256  " is not a ServiceEnvironment.", ccx);
257 
258  // --- Implementation problems --- //
259  } catch (IllegalArgumentException argx) {
260  /* Thrown by Constructor.newInstance to indicate that formal
261  * parameters and provided arguments are not compatible. Since
262  * the constructor doesn't take any arguments, and we didn't
263  * provide any, we shouldn't be able to get here.
264  */
265  throw new AssertionError(argx);
266  }
267  /* If any other RuntimeException or Error gets thrown above, it's
268  * either a bug in the implementation of this method or an
269  * undocumented behavior of the Java standard library. In either
270  * case, there's not much we can do about it, so let the exception
271  * propagate up the call stack as-is.
272  */
273  }
274 
275  // -----------------------------------------------------------------------
276  // Instance Methods
277  // -----------------------------------------------------------------------
278 
283  public abstract ServiceProviderInterface getSPI();
284 
285 
286  // --- From DDSObject: ---------------------------------------------------
287 
288  @Override
290  return this;
291  }
292 
293 
294  // --- Private methods: --------------------------------------------------
295 
311  private static ClassLoader getDefaultClassLoader() {
312  // --- Get class loader from this class --- //
313  ClassLoader classLoader =
314  ServiceEnvironment.class.getClassLoader();
315  if (classLoader != null) {
316  return classLoader;
317  }
318 
319  // --- Fallback: get system class loader --- //
320  /* The class loader is probably the bootstrap class loader, which is
321  * not directly accessible. Substitute the system class loader if
322  * possible.
323  */
324  try {
325  classLoader = ClassLoader.getSystemClassLoader();
326  } catch (SecurityException sx) {
328  ERROR_STRING + "Prevented by security manager.",
329  sx);
330  } catch (IllegalStateException isx) {
331  /* The documentation for ClassLoader.getSystemClassLoader()
332  * says this is thrown if the system class loader tries to
333  * instantiate itself recursively. This situation should not
334  * occur unless a custom system class loader is injected
335  * which uses DDS.
336  */
338  ERROR_STRING +
339  "Circular system class loader dependencies.",
340  isx);
341  } catch (Error err) {
342  /* The documentation for ClassLoader.getSystemClassLoader() says
343  * this is thrown if the system class loader cannot be
344  * reflectively instantiated.
345  */
347  ERROR_STRING +
348  "System class loader could not be initialized.",
349  err.getCause());
350  }
351 
352  // --- Check for null return result --- //
353  /* The documentation for ClassLoader.getSystemClassLoader() says that
354  * the method may return null if there is no system class loader.
355  * However, it doesn't say why that would be the case.
356  *
357  * Do this check outside of the try/catch above to make sure that
358  * no exceptions thrown below will be handled incorrectly. The
359  * exception handling logic above is closely tied to the documented
360  * behavior of ClassLoader.getSystemClassLoader().
361  */
362  if (classLoader == null) {
364  ERROR_STRING + "No system class loader available.");
365  }
366  return classLoader;
367  }
368 
369  // -----------------------------------------------------------------------
370  // Service-Provider Interface
371  // -----------------------------------------------------------------------
372 
378  public static interface ServiceProviderInterface {
379  // --- Singleton factories: ------------------------------------------
380 
382 
384 
385 
386  // --- Types: --------------------------------------------------------
387 
411  public <TYPE> TypeSupport<TYPE> newTypeSupport(
412  Class<TYPE> type, String registeredName);
413 
414 
415  // --- Time & Duration: ----------------------------------------------
416 
423  public Duration newDuration(long duration, TimeUnit unit);
424 
428  public Duration infiniteDuration();
429 
433  public Duration zeroDuration();
434 
443  public ModifiableTime newTime(long time, TimeUnit units);
444 
448  public Time invalidTime();
449 
450 
451  // --- Instance handle: ----------------------------------------------
452 
453  public InstanceHandle nilHandle();
454 
455 
456  // --- Conditions & WaitSet: -----------------------------------------
457 
459 
460  public WaitSet newWaitSet();
461 
462  // --- Status: -------------------------------------------------------
463 
464  public Set<Class<? extends Status>> allStatusKinds();
465 
466  public Set<Class<? extends Status>> noStatusKinds();
467 
468  // --- QoS Provider --------------------------------------------------
481  public abstract QosProvider newQosProvider(String uri, String profile);
482 
483  // --- PolicyFactory -----------------------------------------------------
484 
489  public abstract PolicyFactory getPolicyFactory();
490 
491  public abstract DynamicDataFactory getDynamicDataFactory();
492 
493  // --- Built-in Types -----------------------------------------------------
494 
495  public abstract KeyedString newKeyedString();
496 
497  public abstract KeyedBytes newKeyedBytes();
498  }
499 }
abstract PolicyFactory getPolicyFactory()
Provides an instance of org.omg.dds.core.policy.PolicyFactory.
A GuardCondition object is a specific Condition whose triggerValue is completely under the control of...
static final String IMPLEMENTATION_CLASS_NAME_PROPERTY
A WaitSet object allows an application to wait until one or more of the attached org.omg.dds.core.Condition objects has a triggerValue of true or else until the timeout expires.
Definition: WaitSet.java:117
ModifiableTime newTime(long time, TimeUnit units)
Construct a specific instant in time.
abstract ServiceProviderInterface getSPI()
This method is not intended for use by applications.
Indicates that a DDS implementation could not be initialized due to an error that occurred within tha...
static ServiceEnvironment createInstance(ClassLoader classLoader)
Create and return a new instance of a concrete implementation of this class with the given environmen...
public< TYPE > TypeSupport< TYPE > newTypeSupport(Class< TYPE > type, String registeredName)
Create a new org.omg.dds.type.TypeSupport object for the given physical type.
An opaque handle that can be used to refer to a local or remote entity.
Indicates that a DDS implementation could not be loaded because the either the request to do so or th...
A supertype of all DDS classes and interfaces.
Definition: DDSObject.java:25
This interface is for the use of the DDS implementation, not of DDS applications. ...
The sole purpose of this class is to allow the creation and destruction of org.omg.dds.domain.DomainParticipant objects.
The QoS provider API allows users to specify the QoS settings of their DCPS entities outside of appli...
final ServiceEnvironment getEnvironment()
TypeSupport is an abstract interface that has to be specialized for each concrete type that will be u...
Duration newDuration(long duration, TimeUnit unit)
Construct a org.omg.dds.core.Duration of the given magnitude.
A span of elapsed time expressed with nanosecond precision.
Definition: Duration.java:35
static ServiceEnvironment createInstance(String implClassNameProperty, Map< String, Object > environment, ClassLoader classLoader)
Look up the system property identified by the given string and load, then instantiate, the ServiceEnvironment implementation class identified by its value.
DDS implementations are rooted in this class, a concrete subclass of which can be instantiated based ...
abstract QosProvider newQosProvider(String uri, String profile)
Create a QosProvider fetching QoS configuration from the specified URI.
A moment in time expressed with nanosecond precision (though not necessarily nanosecond accuracy)...
Definition: Time.java:34
Status is the abstract root class for all communication status objects.
Definition: Status.java:41