Evaluating Java Runtime Reflection for Implementing Cross-Language Method Invocations
Total Page:16
File Type:pdf, Size:1020Kb
Evaluating Java Runtime Reflection for Implementing Cross-Language Method Invocations Stefan Sobernig Uwe Zdun Institute for Information Systems and New Media, Information Systems Institute, Vienna University of Vienna University of Economics and Business, Austria Technology, Austria [email protected] [email protected] Abstract two object-oriented languages with one serving as the host (imple- Cross-language method invocations are commonly used for inte- menting) and with the other being the embedded (implemented) grating objects residing in different programming language envi- language. When creating an embedded language, its core and its ronments. In this experience report, we evaluate the performance runtime environment are implemented in the host language. As our and the design impact of alternative implementations of cross- evaluation artifact, we review the case of the Frag language [13]. language method invocations for the object-oriented scripting lan- Frag is a dynamic, object-oriented scripting language implemented guage Frag, implemented and embedded in Java. In particular, in Java, and it provides for developing internal and external DSLs we compare reflective integration and generative integration tech- on top of it [35]. While, in general, this kind of language inte- niques. For that, we present a performance evaluation based on a gration is motivated by providing seamless access to components large set of test cases. In addition, we propose a new method for implemented in the host language, the Frag case presented here is quantifying and comparing the implementation efforts needed for also about facilitating the process of refactoring embedded into host cross-language method invocations based on cross-language refac- code, especially in support of DSL prototyping. torings. We report on the lessons learnt and discuss the conse- Integrating two OO languages can cover different kinds of lan- quences of the implementation variants under review. guage features to varying extents. In particular, two language mod- els and execution environments must be aligned [11, 15, 28]. This Categories and Subject Descriptors D.1.5 [Software]: Pro- includes, for instance, different schemes of object creation and ob- gramming Techniques—Object-oriented Programming; D.3.2 ject life-cycling, object-type handling and type systems, divergent [Language Classifications]: Object-oriented languages; D.2.8 kinds of classification and inheritance relationships, as well as dif- [Software Engineering]: Metrics—Complexity measures, Perfor- ferences in message passing and distinct reflection facilities. In the mance measures following, we limit ourselves to the issue of cross-language method invocations [11, 29]. That is, we put emphasis on evaluating de- General Terms Languages, Measurement, Performance sign choices when bridging message passing, method lookups, and Keywords Reflection, cross-language method invocation, method dispatching between the embedded and the host language. domain-specific languages, refactoring, design science For implementing cross-language method invocations, forms of re- flective and non-reflective integration are available. For the scope of this paper, reflective integration means runtime reflection. More 1. Introduction precisely, we look at the Java-specific forms of runtime introspec- Object-oriented (OO) language systems and derivatives thereof, tion and meta-level reification, as available through the Java Re- such as component-oriented systems and systems built using dis- flection API. By non-reflective integration we refer to generative tributed object systems, regularly need to be integrated. In all of integration techniques. These include kinds of static code genera- these cases, forms of language interoperation are needed. Typical tion, i.e., source-to-source transformation, while excluding runtime scenarios of language interoperation are, for instance, the two-way kinds of code generation [7]. We selected Frag [13] because it uses interactions between language-specific components written in two cross-language method invocations in a ubiquitous manner, turning different languages (e.g., using Java and C++ in one system [34]), the adoption of appropriate Java implementation techniques into a multi-language virtual machines [11, 28], and implementations of critical design decision. one language by means of another. This is the case for dynamic, Whatever features are aligned and integrated, language interop- scripting, and domain-specific languages (DSLs) which are imple- eration aims at representing data structures of one language in the mented on top of host languages such as Java, C#, C++, or C. realm of the other and at calling from one language into the other. In this paper, we are concerned with the latter area of language Ideally, cross-language data representation and cross-language in- interoperation: We provide an empirical evaluation of integrating struction calling are implemented in a symbiotic manner [15]. This requires the data and protocol integration between two languages to be transparent (e.g., avoiding explicit, language-level wrapper structures) and symmetric (e.g., transparent method calls are avail- Permission to make digital or hard copies of all or part of this work for personal or able in both directions). Also, if available at all, a language’s meta classroom use is granted without fee provided that copies are not made or distributed level is to be exposed to the other language (e.g., message reifica- for profit or commercial advantage and that copies bear this notice and the full citation tion as provided in some meta-object protocols). The integration on the first page. To copy otherwise, to republish, to post on servers or to redistribute scenario studied in this paper is partially symbiotic. We focus on to lists, requires prior specific permission and/or a fee. one-way, asymmetric cross-language method invocations, that is, PPPJ ’10, September 15–17, 2010, Vienna, Austria. Copyright ⃝c 2010 ACM 978-1-4503-0269-2. $10.00 invocations from within the embedded into the host language and not vice versa. Also, we do not reflect on meta-level integration formed for each and every host method that should be exposed. for cross-language method invocations. That is, we do not expose In addition, depending on the implementation variant, the wrapper reifications as provided by the Java Reflection API (e.g., instances code has to be maintained at multiple locations to manage single of the java.lang.reflect.Method class) to the embedded lan- host methods (see Section 3 for an actual implementation). guage. Code generation can be used to automate these recurring tasks Despite our not perfectly symbiotic and thus relaxed integration by transforming interface descriptions into dispatch wrappers at de- scenario, we could not identify substantial guidance on making de- sign (or compile) time. In the middleware context, you may think of sign and implementation decisions for cross-language method in- code generators for client proxies and invokers based on interface vocations in related work on cross-language integration. From the description languages such as the Interface Description Language viewpoint of developers of embedded languages or DSL develop- (IDL) or the Web Service Description Language (WSDL). In the ers considering a DSL development platform for adoption, there is programming language integration context this involves wrapper a lack of documented and systematic evaluations of existing lan- generators and their interface description format (such as SWIG guage designs and language implementations. This is problematic [32]). Code generation does not need to be performed at design because of the considerable variety of reflective and non-reflective time only; for example, embedded compilers such as Janino [20] techniques available for implementing cross-language method in- allow us to generate code at runtime, too. Using generated dis- vocations in Java (and beyond). patch wrappers, however, requires developers to put in additional The contributions of this paper are twofold: On the one hand, development efforts and to understand yet another language arti- we propose a new method for quantifying and comparing the ef- fact ([33]). Alternatively, we might need to devise forms of static forts needed for cross-language method invocations based on cross- reflection (i.e., design or compile time reification and introspection language refactorings. On the other hand, we present a perfor- of host language code) to feed code generators. For both, hand- mance evaluation of two cross-language method invocation imple- written and generated dispatch wrappers, the runtime behaviour mentations for the Java implementation of the Frag [13] language (e.g., regarding performance and scalability) is comparable, once core. Our familiarity with Frag’s implementation and the availabil- the generation has been performed. ity of a large test suite covering the entire feature set of this lan- A general alternative to the above solutions are reflective wrap- guage (e.g., garbage collection, string and list manipulation, call- pers. A runtime method reflection infrastructure provides applica- stack management) permit us to compare cross-language method tion meta-data to construct and perform invocations (i.e., invocation invocations quantitatively in a benchmark setting. We report on the target, parameters, parameter types, etc.) at runtime. The methods lessons learnt and discuss this approach for evaluating the adop- of