I am trying to understand why a synchronized block is used in this method from the vertx handlebars library io.vertx.ext.web.templ.handlebars.impl.HandlebarsTemplateEngineImpl class:
#Override
public void render(Map<String, Object> context, String templateFile, Handler<AsyncResult<Buffer>> handler) {
try {
int idx = templateFile.lastIndexOf('/');
String prefix = "";
String basename = templateFile;
if (idx != -1) {
prefix = templateFile.substring(0, idx);
basename = templateFile.substring(idx + 1);
}
Template template = isCachingEnabled() ? cache.get(templateFile) : null;
if (template == null) {
synchronized (this) {
loader.setPrefix(prefix);
// Strip leading slash from Utils##normalizePath
template = handlebars.compile(basename);
if (isCachingEnabled()) {
cache.put(templateFile, template);
}
}
}
Context engineContext = Context.newBuilder(context).resolver(getResolvers()).build();
handler.handle(Future.succeededFuture(Buffer.buffer(template.apply(engineContext))));
} catch (Exception ex) {
handler.handle(Future.failedFuture(ex));
}
}
Please explain it to me like I'm an idiot!
First, synchronization questions are never "idiot" questions.
I spent some time looking at this code too, and still not 100% sure it's totally correct.
The main reason to have synchronized block here is to protect the following two methods from executing out of order:
loader.setPrefix(prefix);
...
template = handlebars.compile(basename);
You see, Handlebars has a reference to loader:
loader = new Loader(vertx);
...
handlebars = new Handlebars(loader);
Possible scenario without sync block would be
T1 sets prefix to A and switches
T2 sets prefix to B and switches
T1 compiles template with prefix set to B, while thinking it's still A
Related
Working on a pretty printer. Based on my understanding of ANTLR and StringTemplate so far, if I want to match all my grammar rules to templates and apply the template each time the grammar rule is invoked, I can create my templates with names matching my grammar rules.
[Side question: Is this how I should approach it? It seems like ANTLR should being doing the work of matching the parsed text to the output templates. My job will be to make sure the parser rules and templates are complete/correct.]
I think ANTLR 3 allowed directly setting templates inside of the ANTLR grammar, but ANTLR 4 seems to have moved away from that.
Based on the above assumptions, it looks like the MyGrammarBaseListener class that ANTLR generates is going to be doing all the work.
I've been able to collect the names of the rules invoked while parsing the text input by converting this example to ANTLR 4. I ended up with this for my enterEveryRule():
#Override public void enterEveryRule(ParserRuleContext ctx) {
if (builder.length() > 0) {
builder.append(' ');
}
if (ctx.getChildCount() > 0) {
builder.append('(');
}
int ruleIndex = ctx.getRuleIndex();
String ruleName;
if (ruleIndex >= 0 && ruleIndex < ruleNames.length) {
ruleName = ruleNames[ruleIndex];
System.out.println(ruleName); // this part works as intended
}
else {
ruleName = Integer.toString(ruleIndex);
}
builder.append(ruleName);
// CONFUSION HERE:
// get template names (looking through the API to figure out how to do this)
Set<String> templates = (MyTemplates.stg).getTemplateNames()
// or String[] for return value? Java stuff
// for each ruleName in ruleNames
// if (ruleName == templateName)
// run template using rule children as parameters
// write pretty-printed version to file
}
The linked example applies the changes to create the text output in exitEveryRule() so I'm not sure where to actually implement my template-matching algorithm. I'll experiment with both enter and exit to see what works best.
My main question is: How do I access the template names in MyTemplates.stg? What do I have to import, etc.?
(I'll probably be back to ask about matching up rule children to template parameters in a different question...)
Following demonstrates a simple way of dynamically accessing and rendering named StringTemplates. Intent is to build varMap values in the listener (or visitor) in its corresponding context, keyed by parameter name, and call the context dependent named template to incrementally render the content of the template.
public class Render {
private static final String templateDir = "some/path/to/templates";
private STGroupFile blocksGroup;
private STGroupFile stmtGroup;
public Render() {
blocksGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Blocks.stg"));
stmtGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Statements.stg"));
}
public String gen(GenType type, String name) {
return gen(type, name, null);
}
/**
* type is an enum, identifying the group template
* name is the template name within the group
* varMap contains the named values to be passed to the template
*/
public String gen(GenType type, String name, Map<String, Object> varMap) {
Log.debug(this, name);
STGroupFile stf = null;
switch (type) {
case BLOCK:
stf = blocksGroup;
break;
case STMT:
stf = stmtGroup;
break;
}
ST st = stf.getInstanceOf(name);
if (varMap != null) {
for (String varName : varMap.keySet()) {
try {
st.add(varName, varMap.get(varName));
} catch (NullPointerException e) {
Log.error(this, "Error adding attribute: " + name + ":" + varName + " [" + e.getMessage() + "]");
}
}
}
return st.render();
}
}
The new Couchbase SDK makes bulk operations easier to use and more performant use rx-java. But is there any value to using rx for operations on single values?
If we look at a simple CAS / insert operation, ie if the value exists do a cas else do an insert and return the document value
final String id = "id";
final String modified = "modified";
final int numCasRetries = 3;
Observable
.defer(() -> bucket.async().get(id))
.flatMap(document -> {
try {
if (document == null) {
JsonObject content = JsonObject.create();
content.put(modified, new Date().getTime());
document = bucket.insert(JsonDocument.create(id, content));
} else {
document.content().put(modified, new Date().getTime());
document = bucket.replace(document);
}
return Observable.just(document);
} catch (CASMismatchException e) {
return Observable.error(e);
}
})
.retry((count, error) -> {
// Only retry on CASMismatchException
return ((error instanceof CASMismatchException)
&& (count < numCASRetries));
})
.onErrorResumeNext(error -> {
return Observable.error(new Exception(error));
})
.toBlocking()
.single();
So toBlocking will block the calling thread until a result is available. and only one value is written and read from Couchbase at a time. So I do not understand why or even if this code will be any better than
final String id = "id";
final String modified = "modified";
final int numCasRetries = 3;
JsonDocument document = null;
for (int i = 1; i <= numCasRetries; i++) {
document = bucket.get(id);
try {
if (document == null) {
JsonObject content = JsonObject.create();
content.put(modified, new Date().getTime());
document = bucket.insert(JsonDocument.create(id, content));
} else {
document.content().put(modified, new Date().getTime());
document = bucket.replace(document);
}
return document;
} catch (CASMismatchException e) {
if (i == numCasRetries) {
throw e;
}
}
}
If anything I'd argue that in this scenario the rx approach is less readable.
For an operation on a single document where ultimately you need to block, I'd tend to agree that your second example is clearer.
RxJava shines when you heavily use asynchronous processing, especially when you need advanced error handling, retry scenarii, combination of asynchronous flows...
The previous generation of Couchbase Java SDK (1.4.x) just had Future for that, and it didn't provide the elegant, powerful and expressive capabilities we found in RxJava.
using Jsoup, I extract JavaScript part in html file. and store it as java String Object.
and I want to extract function list, variables list in js's function using javax.script.ScriptEngine
JavaScript part has several function section.
ex)
function a() {
var a_1;
var a_2
...
}
function b() {
var b_1;
var b_2;
...
}
function c() {
var c_1;
var c_2;
...
}
My Goals is right below.
List funcList
a
b
c
List varListA
a_1
a_2
...
List varListB
b_1
b_2
...
List varListC
c_1
c_2
...
How can I extract function list and variables list(or maybe values)?
I think you can do this by using javascript introspection after having loaded the javascript in the Engine - e.g. for functions:
ScriptEngine engine;
// create the engine and have it load your javascript
Bindings bind = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Set<String> allAttributes = bind.keySet();
Set<String> allFunctions = new HashSet<String>();
for ( String attr : allAttributes ) {
if ( "function".equals( engine.eval("typeof " + attr) ) ) {
allFunctions.add(attr);
}
}
System.out.println(allFunctions);
I haven't found a way to extract the variables inside functions (local variables) without delving in internal mechanics (and thus unsafe to use) of the javascript scripting engine.
It is pretty tricky. ScriptEngine API seems not good for inspecting the code. So, I have such kind of pretty ugly solution with instance of and cast operators.
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
for (Map.Entry<String, Object> scopeEntry : bindings.entrySet()) {
Object value = scopeEntry.getValue();
String name = scopeEntry.getKey();
if (value instanceof NativeFunction) {
log.info("Function -> " + name);
NativeFunction function = NativeFunction.class.cast(value);
DebuggableScript debuggableFunction = function.getDebuggableView();
for (int i = 0; i < debuggableFunction.getParamAndVarCount(); i++) {
log.info("First level arg: " + debuggableFunction.getParamOrVarName(i));
}
} else if (value instanceof Undefined
|| value instanceof String
|| value instanceof Number) {
log.info("Global arg -> " + name);
}
}
I had similar issue. Maybe it will be helpfull for others.
I use groove as script lang. My Task was to retrive all invokable functions from the script. And then filter this functions by some criteria.
Unfortunately this approach is usefull only for groovy...
Get script engine:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
Compile and evaluate script:
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
Get functions from script. I did not found other ways how to get all invokable methods from script except Reflection. Yeah, i know that this approach depends on ScriptEngine implementation, but it's the only one :)
public List getInvokableList() throws ScriptException {
List list = new ArrayList();
try {
Class compiledClass = compiledScript.getClass();
Field clasz = compiledClass.getDeclaredField("clasz");
clasz.setAccessible(true);
Class scrClass = (Class)clasz.get(compiledScript);
Method[] methods = scrClass.getDeclaredMethods();
clasz.setAccessible(false);
for (int i = 0, j = methods.length; i < j; i++) {
Annotation[] annotations = methods[i].getDeclaredAnnotations();
boolean ok = false;
for (int k = 0, m = annotations.length; k < m; k++) {
ok = annotations[k] instanceof CalculatedField;
if (ok) break;
}
if (ok)
list.add(methods[i].getName());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
}
return list;
}
In my task i don't need all functions, for this i create custom annotation and use it in the script:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface CalculatedField {
}
Script example:
import com.vssk.CalculatedField;
def utilFunc(s) {
s
}
#CalculatedField
def func3() {
utilFunc('Testing func from groovy')
}
Method to invoke script function by it's name:
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
In Javascript i have the following code:
var r=applet.foo({var0:99,var1:'foo',var2:applet});
In my Java applet i have the following:
public JSObject foo(JSObject args){
System.out.println("The function is correctly invoked");
//In fact, the following works perfectly:
System.out.println("var1 is:"+(String)args.getMember("var1"));
JSObject w=JSObject.getWindow(this);
JSObject j=(JSObject)w.eval("new Object();");
Map m=new Hashmap();
//TODO here all the keys and values of args should be added to m
m.put("hello","world");
//TODO here all the keys and values of m should be added to j
return j;
}
How can this be done? (TODOs)
Reading http://docstore.mik.ua/orelly/web/jscript/ch19_06.html, i noticed theres a getSlot method for JSObject but if i do
args.getSlot(0)
all i have is one Exception:
netscape.javascript.JSException: No such slot 0 on JavaScript object
...
Unfortunately, Errandir's solution works only when you know a name of global variable that can be used to access an object you want to get properties' names of. You need to know this name to be able to add keys method to the object, and invoke it using JSObject's call method later. Of course, you can pass a global name of your object to Java if you have it. This solution doesn't look so good especially when you can't refer to your object in global context.
As an alternative, I proposed to use this of JSObject's eval method in the comment supposing that it will do all the work. And it does. But a big disappointent was that it works as expected only in Mozilla Firefox and Opera. In Internet Explorer 9 and Google Chrome (tested under Windows 7 and Ubuntu 12.04 LTS) this of eval method always refers to applet's document window ignoring which JavaScript object JSObject instance actually represents. I don't know whether it's a bug or simply LiveConnect is supported in these browsers very poorly.
The good news is that call method of JSObject executes specified function on the proper context. Keeping that in mind I finally found a solution how a list of names of JavaScript object's properties can be retrieved. The idea is to define a temporary function in global context using eval method. This function has to receive a JavaScript object we want to get properties of and to return names of these properties as an array. After that we can invoke the temporary function through JSObject's call method passing a Java representation of concerned JavaScript object (jsObject in my method below or args as it sounds in the question). At last, temporary function can be removed.
public static ArrayList<String> getJsObjectPropertiesNames(Applet applet, JSObject jsObject) {
if (applet == null || jsObject == null)
return null;
// Retrieving global context - a JSObject representing a window applet belongs to
JSObject globalContext;
try {
globalContext = JSObject.getWindow(applet);
}
catch (JSException ex) {
return null;
}
// Checking whether passed object is not an array
try {
jsObject.getSlot(0);
return null;
}
catch (JSException e) {
}
String keysFunctionName = String.format("_getKeys%d", Calendar.getInstance().getTimeInMillis());
jsObject.eval("window['" + keysFunctionName + "'] = function(jsObject) { return Object.keys(jsObject) }");
JSObject propertiesNamesJsObject = (JSObject)globalContext.call(keysFunctionName, new Object[] { jsObject });
jsObject.eval("delete(window['" + keysFunctionName + "'])");
ArrayList<String> propertiesNames = new ArrayList<>();
try {
int slotIndex = 0;
while (true) {
Object propertyName = propertiesNamesJsObject.getSlot(slotIndex);
if (propertyName instanceof String)
propertiesNames.add((String)propertyName);
slotIndex++;
}
}
catch (JSException e) {
}
return propertiesNames;
}
As a solution, you could define method keys as proposed here (You can do it within your java-code using JSObject.eval(...)). Then you could get keys like:
JSObject keys = (JSObject)args.call("keys", Collections.EMPTY_LIST);
keys.getSlot(0);
Here below I print a String, please modify it to get whatever you need.
public final static String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}";
private static String printProperties(final Object o,
final boolean printType,
final int level,
final String tab) {
final StringBuilder sb = new StringBuilder(100);
if (printType) {
sb.append("(");
sb.append(o.getClass().getSimpleName());
sb.append(") ");
}
if (o instanceof JSObject) {
sb.append("{\n");
final JSObject js = (JSObject) o;
final JSObject keys = (JSObject) js.eval(getKeys);
boolean needComma = false;
for (int i = 0;; i++) {
final String key = (String) keys.getSlot(i);
if ((key != null) && !(key.equals("undefined"))) {
final Object val = js.getMember(key);
if (!needComma) {
needComma = true;
} else {
sb.append(",\n");
}
sb.append(multitab(tab, level));
sb.append(key);
sb.append(":");
sb.append(printProperties(val, printType, level + 1, tab));
} else {
break;
}
}
sb.append("\n");
sb.append(multitab(tab, level - 1));
sb.append("}");
} else {
sb.append(o);
}
return sb.toString();
}
private final static String tab = " ";
private static String multitab(final String tab,
int i) {
final StringBuilder sb = new StringBuilder();
while (i-- > 0) {
sb.append(tab);
}
return sb.toString();
}
I have a MDB running in WebSphere, when it tries to pull a message off an MQ Queue
the following exception is thrown:
com.ibm.mq.MQException: Message catalog not found
Any idea how to resolve this?
Add the directory containing the mqji.properties file to the CLASSPATH
Google says it's a missed entry in the classpath:
http://www.mqseries.net/phpBB2/viewtopic.php?t=5979&highlight=mqji
The mqji.properties files is already included in the mq jar file.
The Message Catalog not found exception is thrown as part of a "MQJMS2002: failed to get message from MQ queue".
It turns out that this error was thrown because I had the Queue Connection Factory defined
at server level (on the WebSphere v6 server) and the wrong classloader was being used to
load the above mentioned properties file.
I solved the issue by redefining factory at cell level.
Since the error message you'll be getting with the message catalog is pretty useless, too, here is a little patch for the mq.jar:
Get jad
Disassemble MQException and MQInternalException (the latter is only necessary because it inherits from MQException; we won't change it).
Add this code to MQException:
// PATCH New fields
private final static IntHashMap completionCodes = new IntHashMap ();
private final static IntHashMap reasonCodes = new IntHashMap ();
static
{
addCodes (completionCodes, "MQCC_");
addCodes (reasonCodes, "MQRC_");
}
/**
* PATCH Create a map of names for the MQ error codes
*
* #param map
* #param prefix
*/
private static void addCodes(IntHashMap map, String prefix)
{
Field[] field = MQException.class.getFields();
try
{
for (int i = 0; i < field.length; i++)
{
String name = field[i].getName();
if (name.startsWith(prefix))
{
name = name.substring(prefix.length());
int value = field[i].getInt(null);
map.put (value, name);
}
}
}
catch (IllegalArgumentException e) {
throw new RuntimeException (e);
}
catch (IllegalAccessException e) {
throw new RuntimeException (e);
}
}
Replace getMessage() with this code:
// PATCH Complete rewrite
public String getMessage()
{
if(ostrMessage == null) {
String rc = (String)reasonCodes.get(reasonCode);
if (rc == null)
rc = "ReasonCode "+reasonCode;
String cc = (String)completionCodes.get(completionCode);
if (cc == null)
cc = "CompletionCode "+completionCode;
String message = "MQJE001: "+cc+" "+rc;
if(msgId == 0)
ostrMessage = message;
else {
String s = msgId+" {0} {1}";
if (exceptionMessages != null) {
s = exceptionMessages.getString(Integer.toString(msgId));
}
if(numInserts > 0) {
Object as1[] = new String[numInserts];
if(numInserts > 0) as1[0] = insert1;
if(numInserts > 1) as1[1] = insert2;
s = MessageFormat.format(s, as1);
}
ostrMessage = message+"\n"+s;
}
if (underlyingException != null)
ostrMessage = ostrMessage + "\n" + underlyingException.getMessage();
}
return ostrMessage;
}
Either compile these two classes into a new jar or patch the original mq.jar.
Instead of the MQJE001: RC 2 CC 2035, you'll get "MQJE001: FAILED NOT_AUTHORIZED"