Skip to content

Instantly share code, notes, and snippets.

@Oifan
Last active May 28, 2018 19:48
Show Gist options
  • Save Oifan/22df3556ea46a41f771987b93942ca34 to your computer and use it in GitHub Desktop.
Save Oifan/22df3556ea46a41f771987b93942ca34 to your computer and use it in GitHub Desktop.
[Rhino-X-Java - hiddenField] Accessing Java members from Rhino JS Engine
[Rhino-X-Java - hiddenField]
Accessing Java members from Rhino JS Engine
#!/bin/sh
URL=https://gist.github.com/Oifan/22df3556ea46a41f771987b93942ca34/raw/43a252ce8bce19991d59636dc562ea3f2c6e770f
mkdir lib
mkdir src
wget "$URL/hidden.sh"
wget -O src/mk.sh "$URL/src%2523mk.sh"
wget -O src/HiddenField.java "$URL/src%2523HiddenField.java"
wget -O src/hiddenField.js "$URL/src%2523hiddenField.js"
chmod 755 hidden.sh src/mk.sh
echo '[i] Download COMPLETE :-)'
echo ' * To COMPILE this example --> Run src/mk.sh'
echo ' * To RUN this (after COMPILE) --> Run hidden.sh'
#!/bin/sh
RHINO_VER=1.7.10
#RHINO_VER=1.7.9
[ -f "lib/rhino-$RHINO_VER.jar" ] || wget -Plib "http://central.maven.org/maven2/org/mozilla/rhino/$RHINO_VER/rhino-$RHINO_VER.jar"
CPSEP=':'
[ -z "${WINDIR}" ] || CPSEP=';'
JAVACP=lib/hidden.jar${CPSEP}lib/rhino-$RHINO_VER.jar
java -cp "$JAVACP" org.mozilla.javascript.tools.shell.Main -f src/hiddenField.js
public class HiddenField {
public int hidden = 10;
public boolean hidden() {
return true;
}
}
'use strict';
importClass( java.lang.Class );
importClass( org.mozilla.javascript.Context );
importClass( org.mozilla.javascript.Scriptable );
importClass( Packages.HiddenField );
function getFieldFrom (obj, fldName) {
var field = obj.getClass().getField( fldName );
return field.get( obj );
}
function invokeDeclaredMethod (obj, clazz, methName, methParamTypes, methParams, force) {
var method = clazz.getDeclaredMethod( methName, methParamTypes );
if ( force )
method.setAccessible( true );
var result = method.invoke( obj, methParams );
if ( force )
method.setAccessible( false );
return result;
}
function showInfo (member) {
print( 'typeof\t= ' + typeof member );
if (typeof member == 'function') {
print( '------ toSource() ------' );
print( member.toSource() );
} else {
print( 'value\t= ' + member + '\n' );
}
}
//---------------------------[ MAIN PROGRAM ]---------------------------
print( '[ ' + Context.currentContext.implementationVersion + ' ]\n' );
var hidnFldObj = new Packages.HiddenField();
print( '#######[ PROBLEM DESCRIPTION ]#######\n' );
print( 'Having an instance of class HiddenField (see src/HiddenField.java),');
print( 'we want to access its member -- public int hidden.');
print( 'In Java this could be done with: "new HiddenField().hidden".\n');
print( '########[ EXPECTED BEHAVIOR ]########\n' );
print( "****[ APPROACH 0: using Java reflection ]****" );
var hidnFldMembr0 = getFieldFrom( hidnFldObj, 'hidden' );
showInfo( hidnFldMembr0 );
// typeof = object
// value = 10
print( '########[ ACTUAL BEHAVIOR ]########\n' );
print( "****[ APPROACH 1: new Packages.HiddenField().hidden ]****" );
var hidnFldMembr1 = hidnFldObj.hidden;
showInfo( hidnFldMembr1 );
// typeof = function
// ------ toSource() ------
// function hidden() {/*
// boolean hidden()
// */}
print( "****[ APPROACH 2: new Packages.HiddenField()['hidden'] ]****" );
var hidnFldMembr2 = hidnFldObj['hidden'];
showInfo( hidnFldMembr2 );
// *** SAME AS 'APPROACH 1' ***
print( "****[ APPROACH 3: using Rhino's JavaMembers.lookupClass and JavaMembers.get ]****" );
var javaMembersClz = Class.forName( 'org.mozilla.javascript.JavaMembers' );
var javaMembers = invokeDeclaredMethod(
null, javaMembersClz, 'lookupClass',
[ Scriptable, Class, Class, java.lang.Boolean.TYPE ],
[ this, HiddenField, HiddenField, false ],
true );
var hidnFldMembr3 = invokeDeclaredMethod(
javaMembers, javaMembersClz, 'get',
[ Scriptable, java.lang.String, java.lang.Object, java.lang.Boolean.TYPE ],
[ this, 'hidden', hidnFldObj, false ],
true );
showInfo( hidnFldMembr3 );
// *** SAME AS 'APPROACH 1' ***
// TODO see also https://stackoverflow.com/questions/10483422/intercept-field-access-of-java-objects-in-rhino
#!/bin/sh
javac HiddenField.java
jar cvf ../lib/hidden.jar *.class *.java
[ -d classes ] || mkdir classes
mv *.class classes/
@Oifan
Copy link
Author

Oifan commented May 28, 2018

To download & run this example, do following:

  1. download & run _init.sh --> this will download all other files from this gist
  2. follow instructions at the end of _init.sh --> to compile and run this example

To summarize it in 3 lines:
wget https://gist.github.com/Oifan/22df3556ea46a41f771987b93942ca34/raw/8717635de51412f15139c0dfbdb8b61cb2cbe9dd/_init.sh && . _init.sh
cd src && ./mk.sh
cd .. && ./hidden.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment