Many years ago, after learning several programming languages, I noticed that too often no matter which language I was using, I was missing some feature found on another language. For example, Java misses the overloading of operators or generics of Ada. It also misses the enumerated types of C/C++ or Ada. Programming with these limitations can be done at the cost of more complex code, harder to read, and write without errors. Imagine going back to an exception-unaware language!
I realized a few years ago that XML could be the solution to making a language extensible at will.
For instance, the following piece of Java code:
System.out.println("Hello, World");
could be rewritten as:
<invoke>
<target field-ref="java.lang.System.out"/>
<method method-ref="println(java.lang.String)"/>
<literal type-ref="java.lang.String">Hello, World</literal>
</invoke>
Of course, this XML code is way too long to enter by hand. But, using modern IDEs capabilities can make it a lot easier.
A possible extension to JEX could be in the internationalization area.
In this example the definition of a literal could be modified like such:
<literal typeref="java.lang.String" string-ref="hello-world"/>
and somewhere in the project, a dictionary of literals would contain:
<local-literal id="hello-world">
<en>Hello, World</en>
<fr>Bonjour, le Monde</fr>
</local-literal>
The programmer defining the extension, also defines a (XSLT) transformation to get back to the standard specification of JEX.
By applying a series of transformations, a project gets from a high level - with project- or company-specific extensions - down to the standard level defined by JEX.
When a programmer is hired, he has to learn the company-defined extensions then, when assigned to a project, he needs to learn the extensions defined for this project.
You can check the Visitor pattern provided as an example.
Here is a visitor applied to classes A and B:
<visitor id="V" name="V" parent-ref="java.lang.Object" visibility="public">
<field id="V-out" type-ref="java.io.PrintStream" name="out"/>
<exception type-ref="java.io.IOException"/>
<visit-for type-ref="A">
<invoke-statement function-ref="java.io.PrintStream-println-int-">
<access field-ref="V-out">
<visitor-ref/>
</access>
<access field-ref="A-a"/>
</invoke-statement>
</visit-for>
<visit-for type-ref="B">
<invoke-statement function-ref="java.io.PrintStream-println-int-">
<access field-ref="V-out">
<visitor-ref/>
</access>
<access field-ref="A-a"/>
</invoke-statement>
<invoke-statement function-ref="java.io.PrintStream-println-int-">
<access field-ref="V-out">
<visitor-ref/>
</access>
<access field-ref="B-b"/>
</invoke-statement>
</visit-for>
</visitor>
The "visitor-for" elements will be used to generate the appropriate method in the visited classes.
Here is the generated method for A:
<method type-ref="void" name="visitV" id="visit-V-A">
<parameter name="visitor" type-ref="V" id="VIS-N1010E-VISITOR"/>
<exception type-ref="java.io.IOException"/>
<body>
<invoke-statement function-ref="java.io.PrintStream-println-int-">
<access field-ref="V-out">
<access variable-ref="VIS-N1010E-VISITOR"/>
</access>
<access field-ref="A-a"/>
</invoke-statement>
</body>
</method>
The visitor is invoked by:
<invoke-visitor visitor-ref="V" visit-for="B">
<access variable-ref="V-main-v"/>
<allocate type-ref="B"/>
</invoke-visitor>
Or, in Java:
v.visitV(new B());
This implementation of the Visitor pattern is just an example.
Several providers can compete to offer the best implementation.
Multiple implementation can also co-exist and be used from the same project.
Note: this example also comes with a simple UML Class Diagram.
- outdated -Use drag and drop to convert, transform, verify a XML file.
run 'build.bat' to build jvm.xml-dependent dtd entries, and compile the Java classes.
Disassembling and reassembling
You can disassemble an existing Java class file as follows (from the examples directory):
1 | compile HelloWorld.java |
---|
2 | run 'convert HelloWorld.class' |
---|
3 | run 'transform HelloWorld.jvm' |
---|
Compiling a JEX project
To compile a JEX project into Java class files, do the following:
1 | run 'build HelloWorld.jex' |
---|