-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fails to load when used in AWS Lambda function #175
Comments
Can you provide the full stack traces? There should be a 🏩 |
Hey Kyle ;-) The trace seems maybe different/truncated due to being in Lambda env - there's no "Caused by:", but here's what I get as log output (sadly, the System.out.println's Antlr is doing don't seem to show up either, also that apparently cut beginning of "ke" is exactly the beginning I get, so something is cut off):
Also, it seems to me that it has something to do with initialization of Antlr. I pulled out the
I then ran the Lambda, and got an error in Antlr's |
@kgann doh, my bad - the logs from the test run are truncated. I got the full log, and voila, there's a Caused by, and that shows the reason!
My guess is that the root-level path is causing problems. Also, even more odd, the code shows that it doesn't have that root path separator on the front when it constructs it, so maybe that's added somehow in the loading code. I will dig through and investigate more, but if this sheds any light, let me know. Oh, and here's the full trace:
|
I just created a "hello world" project and ran it on AWS Lambda. Unfortunately I encountered the same issue.
I'll keep exploring this issue and have my team of |
As a note, I know there are newer versions of Antlr. I did a quick try of pulling down clj-antlr, and updating it's Antlr dependency to 4.7.1 (which I believe is the latest). Unfortunately the tests failed. |
I am also experiencing this issue when deployed to AWS as a lambda. Here's another datapoint: It does not manifest itself when pointing to an unzipped .jar directory using sam-local. |
Has anyone found a workaround for this? |
I'm still banging my head on this one. The ANTLR resource is available on the classpath so that is a bit of a red herring. |
The fact that it works locally using SAM Local might mean that the classpath is being constructed differently on AWS. |
I've figured this one out, though I'm still working through how to fix/workaround it. The tl;dr is: AWS Lambda unpacks your jar into a directory off root defined by the env var "LAMBDA_TASK_ROOT", but ANTLR, by way of the StringTemplate4 library and several coercions to/from string, url, uri types, ends up constructing a resource path rooted at /. To make matters worse, ANTLR and StringTemplate4 look for the format filename differently (so you could construct a valid absolute path in antlr to pass to stringtemplate and have it fail the checks in antlr, which correctly use a call to Here is a hacky workaround for the Antlr's ErrorManager class's public void setFormat(String formatName) {
this.formatName = formatName;
String lambdaTaskRoot = System.getenv("LAMBDA_TASK_ROOT");
String fileName = FORMATS_DIR +formatName+STGroup.GROUP_FILE_EXTENSION;
String fileNameForStringTemplateLib = (lambdaTaskRoot != null ? lambdaTaskRoot + "/" : "") + fileName;
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL url = cl.getResource(fileName);
if ( url==null ) {
cl = ErrorManager.class.getClassLoader();
url = cl.getResource(fileName);
}
if ( url==null && formatName.equals("antlr") ) {
rawError("ANTLR installation corrupted; cannot find ANTLR messages format file "+fileName);
panic();
}
else if ( url==null ) {
rawError("no such message format file "+fileName+" retrying with default ANTLR format");
setFormat("antlr"); // recurse on this rule, trying the default message format
return;
}
STGroupFile.verbose = true;
format = new STGroupFile(fileNameForStringTemplateLib, "UTF-8");
format.load();
if ( !initSTListener.errors.isEmpty() ) {
rawError("ANTLR installation corrupted; can't load messages format file:\n"+
initSTListener.toString());
panic();
}
boolean formatOK = verifyFormat();
if ( !formatOK && formatName.equals("antlr") ) {
rawError("ANTLR installation corrupted; ANTLR messages format file "+formatName+".stg incomplete");
panic();
}
else if ( !formatOK ) {
setFormat("antlr"); // recurse on this rule, trying the default message format
}
} |
In the version of Antlr used by this library's clj-antlr dependency it is enough to replace |
I modified ANTLR and Stringtemplate4 to get this working in all deployment scenarios (AOT'd packed jar, AOT'd unpacked jar, repl). PRs here: and I have forks of both libs with the changes: Simply exclude the In the meantime ... what's the level of effort to use Instaparse instead? :) |
We used Instaparse at first but noticed extremely high query parse times for large queries. We moved to Antlr to improve performance. |
I'm worried that Antlr4 and StringTemplate4 are abandoned. 48 open PRs and hundreds of issues against Antlr, likewise many open for ST4. I don't think my PRs will be merged anytime soon. |
@solussd thank you! For any other folks who might come across this and not know the Leiningen and build mechanisms for what @solussd describes above, what I did (and please tell me if there's a better way!) was:
Rebuilt everything (and also had to make sure Cursive reparsed Maven as the REPL wasn't working properly until I did that, in case you use Cursive ;-). |
Update: this issue is fixed upstream now in ANTLR4 4.7.2-SNAPSHOT. |
Fixes file/path open problem on AWS lambda, see: antlr/antlr4#2280 antlr/antlr4@11d6013 Needed by an open Lacinia issue: walmartlabs/lacinia#175 (comment)
First, caveat I'm pretty new to Clojure. I have a small AWS Lambda function that will be a GraphQL endpoint. GraphQL code is working fine in tests and the REPL. However, as soon as I require
com.walmartlabs.lacinia
in any code, the Lambda fails to load, ultimately resulting in an "ANTLR ErrorManager panic" error. I get different stack traces depending on where it's required. Note, requiring the other parts of Lacinia (schema, util, resolve, etc.) all seem fine. Seems to have something to do with initial loading of ANTLR, although I'm able to load and parse my GraphQL schema with...lacinia.schema/compile
without problems. I'm using Lacinia 0.25.0, Clojure 1.9, Java 8.If I have
(:require [com.walmartlabs.lacinia :refer [execute]])
then I see:If I move that require to a different file, then I see:
I'm hoping maybe I am missing something with my configuration or how I need to create my Uberjar or something? I am using
:aot :all
for the Uberjar. Maybe someone can give me some ideas on where to start investigating further?The text was updated successfully, but these errors were encountered: