Reputation: 507
I am trying to use AWS's JDBC Driver to allow a Lambda function running Node 6.10 to connect to AWS Athena and create a database. (I will also want to be able to create and query against tables inside of that databse).
I have tried the following code from an answer to a similar question:
var JDBC = require('jdbc');
var jinst = require('jdbc/lib/jinst');
if (!jinst.isJvmCreated()) {
jinst.addOption("-Xrs");
jinst.setupClasspath(['./AthenaJDBC41-*.jar']);
}
var config = {
// Required
url: 'jdbc:awsathena://athena.us-east-1.amazonaws.com:443',
// Optional
drivername: 'com.amazonaws.athena.jdbc.AthenaDriver',
minpoolsize: 10,
maxpoolsize: 100,
properties: {
s3_staging_dir: 's3://aws-athena-query-results-*/',
log_path: '/logs/athenajdbc.log',
user: 'access_key',
password: 'secret_key'
}
};
var hsqldb = new JDBC(config);
hsqldb.initialize(function(err) {
if (err) {
console.log(err);
}
});
When I run this on my own machine (Mac OSX El Capitan 10.11.6), I see the popup pictured below with the message No Java runtime present, requesting install.
printed to my console.
When I deploy my code to Lambda and run it there, it fails with the following message:
Error: /var/task/node_modules/java/build/Release/nodejavabridge_bindings.node: invalid ELF header
When run locally, I can see that things fail at the var hsqldb = new JDBC(config);
line, but when running on Lambda, the error occurs immediately upon requiring JDBC (the first line of the code above).
The invalid ELF header
issue seems to be pointing to the idea that the node_modules/java/build/Release/nodejavabridge_bindings.node
file was compiled for an architecture incompatible with the one on which AWS Lambda runs (Linux x64).
This explains the difference in behavior when running locally vs when running on Lambda.
I have tried using node-gyp to compile the resource specifically for the x64 architecture, and saw the issue change but not resolve.
The node-gyp command I ran successfully was node-gyp configure --arch=x64
(run inside the node_modules/java/
directory)
Instead of an invalid ELF header
error when running on Lambda, we now see a module initialization error
(See logs below)
module initialization error: Error
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/var/task/node_modules/java/lib/nodeJavaBridge.js:21:16)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
Upvotes: 1
Views: 1450
Reputation: 14029
You are describing a couple of issues here.
First the missing JVM in MacOS. This is a documented bug within node-java. This link describes a workaround for that issue.
https://github.com/joeferner/node-java/issues/90#issuecomment-45613235
After applying that and changing the "setupClasspath"-statment, your sample should be runnable locally.
jinst.setupClasspath(['./AthenaJDBC41-1.0.1.jar']);
As for the ELF-problem, you cannot build Linux native modules for node in MacOS. And since npm does not distribute prebuild versions, you can only build you deployable on a target equivalent machine.
This means you need to install/package your modules on a Linux AMI (preferably the Lambda AMI).
Here an AWS blog post on how to do this:
https://aws.amazon.com/blogs/compute/nodejs-packages-in-lambda/
AMI versions used:
http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html
Upvotes: 2