Design Approaches To Wrapping
Design Approaches To Wrapping
net/publication/270448398
CITATIONS READS
4 888
All content following this page was uploaded by Anna Malinova on 13 September 2018.
Anna Malinova
Key words: design patterns, native code, legacy software, wrapping, JNI
1. Introduction
89
Anna Malinova
process for simulation, as discussed in [12]. The main purpose of this research
is to reuse and integrate codes that have been developed in our group (e.g. [4],
[6]), as well as codes developed by other scientific groups.
In this paper the design patterns are discussed in the context of invo-
king native applications from Java. Two integration options when linking to
programs in other languages have been investigated in [10] and [11]:
The first method has many limitations and is appropriate when the interac-
tion requirements are relatively simple. In contrast, JNI provides rich interface
between native and Java code and is suitable for fine grained interactions. The
latter approach is considered in the rest of the paper.
In the context of creating JNI wrappers, a Java wrapper calls a legacy API
through the created JNI glue code, as it is shown Figure 1.
90
Design Approaches to Wrapping Native Legacy Codes
91
Anna Malinova
Both approaches allow replacement of legacy services when the new ap-
plication no longer needs a native legacy application to provide a service. In
this case, if a new implementation of this functionality is provided, one method
invocation would simply be replaced with another inside the wrapper class.
In the process of creating Java wrappers of native legacy applications,
some well-known object-oriented techniques can be applied, such as design
patterns. Specifically the patterns Adapter and Proxy [3] are considered. Both
are not directly applicable in this situation because here we have client and
adapted code written in different languages. In addition it is often a question
of adapting non-object-oriented legacy software. Bellow the application of the
Wrapper Façade design pattern when wrapping non-object-oriented native code
is also described. [17].
92
Design Approaches to Wrapping Native Legacy Codes
Adapter design pattern relates to creating JNI stub functions in the sense
that it converts the interface of a class into another interface the client expects
[3]. Thus Adapter makes it possible for classes to work together where that
wouldn’t be possible because of incompatible interfaces. This is exactly the
reason for creating a JNI adapter – without it the native class and its Java
wrapper would not be able to work together.
The class version of Adapter uses multiple inheritance to adapt the
Adaptee’s interface to Target’s interface (see Figure 4), and therefore it can-
not be applied with wrapping through JNI since in this case the inheritance is
impossible.
The object version of Adapter realizes the adaptation by using object com-
position, instead of inheritance. Thus an object adapter lets a single Adapter
work with many Adaptees – the Adaptee itself and all of its subclasses (if any).
The object adapter relates to the process of JNI wrapping of native legacy
codes – the client sends request to the Java wrapper class; then the JNI stub
functions, implementing the Java methods declared as native, make the corres-
ponding invocations of the underlying native functions. As a result, the native
interface is adapted to Java interface.
93
Anna Malinova
94
Design Approaches to Wrapping Native Legacy Codes
The design patterns Adapter and Proxy are related. Adapter provides
a different interface to the object it adapts. In contrast, a proxy provides
the same interface as its object. However, a proxy used for access protection
might refuse to perform an operation that the subject will perform, so its
interface may be subset of the subject’s. Java peer classes that wrap native
data structures apply both Adapter and Proxy design patterns. On one hand
the existing C++ interface is adapted to Java interface, and from the other the
peer class serves as a proxy to the native C++ class it represents, taking care
of creating and deleting the instances of this class, and providing interface that
is identical to or a subset of the wrapped one.
Integration with non-object-oriented code, written in such languages as C
and Fortran, is discussed in [13]. The object-oriented re-architecturing tech-
nique presented there implies to use object-oriented architecture (wrapper)
around internal elements that are not object-oriented. Examples of object-
oriented encapsulation, hiding the underlying routines are provided, i.e. the
NAG software from the Numerical Algorithms Group [14]. Although written
in C, the NAG C library’s functionality can be accessed from other higher-level
languages.
The Wrapper Façade design pattern, presented in [17], encapsulates the
functions and data provided by the non-object-oriented legacy native API
within more concise, portable and maintainable object-oriented class inter-
faces, as it is shown in Figure 7. An example of occurrence of Wrapper Façade
pattern can be found in the context of Internet communications, as discussed
in [16]. For efficiency or legacy reasons, many protocols of the TCP stack are
implemented in C. And even though Java, trough the JNI, allows a program-
mer to directly invoke C functions, one or more classes are introduced in order
to separate the protocol from the client application.
95
Anna Malinova
In this section are presented recent results of creating Java front-ends for
some basic functionality of the Plasimo simulation software [15]. The Plasimo
code is multi-physics code for simulating a variety of plasma sources with vari-
ous degrees of equilibrium, electromagnetic field configurations, flow regimes
and geometries [2]. Plasimo is a framework written in C++ and the application
of different wrapping techniques was investigated. The Java Native Interface
was used to produce a class library that wraps a set of Plasimo’s functions and
classes. The aim of this wrapping was to give the legacy code access to the
new web technologies and best practices. For details refer to [9] and [2].
96
97
Figure 8. UML component diagram showing the dependency relations between different
Plasimo components after the Java wrapping
Design Approaches to Wrapping Native Legacy Codes
Anna Malinova
The techniques ”one-to-one mapping” and creating Java peer classes, re-
lated to the Adapter and Proxy design patterns, were applied. The Wrapper
Façade pattern was not used because of the small amount of non-object-oriented
code that was wrapped. As discussed in the previous section, direct access form
the Java class to the non-object code was chosen instead.
In Figure 8 are presented the dependency relationships between different
Plasimo components after the Java front-end was created. The application
JPlasimo is test application that invokes the native methods of the created
Java wrapper classes. The implementation of the native methods is provided
by a set of libraries consisting of JNI stub functions, which in turn invoke the
Plasimo functions inside the Plasimo compiled libraries.
4. Conclusion
5. Acknowledgements
References
98
Design Approaches to Wrapping Native Legacy Codes
99
View publication stats
Anna Malinova
Анна Малинова
100