├── .travis.yml ├── resources ├── Smoketest.class └── Smoketest.java ├── appveyor.yml ├── .gitignore ├── package.json ├── LICENSE ├── test.js ├── install.js ├── README.md └── index.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "5.5.0" 3 | os: 4 | - linux 5 | - osx 6 | -------------------------------------------------------------------------------- /resources/Smoketest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schreiben/node-jre/HEAD/resources/Smoketest.class -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | nodejs_version: "5.5.0" 3 | 4 | install: 5 | - ps: Install-Product node $env:nodejs_version 6 | - npm install 7 | 8 | test_script: 9 | - node --version 10 | - npm --version 11 | - npm test 12 | 13 | build: off 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /jre 2 | *.tar.gz 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Dependency directories 15 | node_modules 16 | jspm_packages 17 | 18 | # Optional npm cache directory 19 | .npm 20 | 21 | # Other ignores 22 | .DS_Store 23 | 24 | # Intellij IDEA 25 | /.idea 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-jre", 3 | "version": "0.2.3", 4 | "description": "Embeds the Java Runtime Environment into a Node.js app", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js", 8 | "install": "node install.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/schreiben/node-jre.git" 13 | }, 14 | "keywords": [ 15 | "node", 16 | "jre", 17 | "java", 18 | "runtime", 19 | "environment", 20 | "embed", 21 | "portable", 22 | "download" 23 | ], 24 | "author": "Tilman Kamp", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/schreiben/node-jre/issues" 28 | }, 29 | "homepage": "https://github.com/schreiben/node-jre#readme", 30 | "dependencies": { 31 | "fs": "0.0.1-security", 32 | "os": "^0.1.1", 33 | "progress": "^2.0.3", 34 | "request": "^2.75.0", 35 | "rimraf": "^2.6.3", 36 | "tar-fs": "^2.0.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 schreiben 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /* MIT License 2 | * 3 | * Copyright (c) 2016 schreiben 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | require('process').exit(require('.').smoketest() ? 0 : 1); 25 | -------------------------------------------------------------------------------- /install.js: -------------------------------------------------------------------------------- 1 | /* MIT License 2 | * 3 | * Copyright (c) 2016 schreiben 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | require('.').install(err => require('process').exit(err ? 1 : 0)); 25 | -------------------------------------------------------------------------------- /resources/Smoketest.java: -------------------------------------------------------------------------------- 1 | /* MIT License 2 | * 3 | * Copyright (c) 2016 schreiben 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | public class Smoketest { 25 | public static void main(String[] args) { 26 | System.out.println("No smoke!"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | > **WARNING**: This repository is not maintained anymore. 3 | > Please use a more up to date solution like [njre](https://github.com/raftario/njre) instead. 4 | 5 | # node-jre 6 | 7 | This module will embed the Java Runtime Environment (JRE) into a Node.js app. 8 | It will download the platform specific JRE at installation time. 9 | Afterwards the embedding app can be bundled into a platform specific package. 10 | This package would not require any further JRE installation steps by users. 11 | 12 | ## Install 13 | 14 | ```bash 15 | npm install --save node-jre 16 | ``` 17 | 18 | ## Usage 19 | 20 | In this example we will run the a Java class-file at the relative path 21 | `java/Hello.class`. It's source code `java/Hello.java` would look like this: 22 | 23 | ```java 24 | public class Hello { 25 | public static void main(String[] args) { 26 | System.out.println("Hello, " + args[0] + "!"); 27 | } 28 | } 29 | ``` 30 | 31 | You can compile it with something like this: 32 | ```bash 33 | javac java/Hello.java 34 | ``` 35 | 36 | By running the following file you should get `true` as output. 37 | 38 | ```javascript 39 | var jre = require('node-jre'); 40 | 41 | var output = jre.spawnSync( // call synchronously 42 | ['java'], // add the relative directory 'java' to the class-path 43 | 'Hello', // call main routine in class 'Hello' 44 | ['World'], // pass 'World' as only parameter 45 | { encoding: 'utf8' } // encode output as string 46 | ).stdout.trim(); // take output from stdout as trimmed String 47 | 48 | console.log(output === 'Hello, World!'); // Should print 'true' 49 | ``` 50 | 51 | ## API 52 | 53 | `jre.install([callback])` Downloads and prepares a Java Runtime Engine (JRE). It is automatically called during module installation. 54 | - `callback` (function(error)). Will be called when installation is finished. In case of any problems, `error` will be defined and contain a description. 55 | 56 | `jre.spawn(classpath, classname[, args][, options])` Spawns a new child process by running the main method of a given Java class. This is a wrapper around [child_process.spawn]. Please look there for further documentation. 57 | - `classpath` (array of strings). Paths to `.jar` files or directories containing `.class`files. 58 | - `classname` (string). The Java class to run. 59 | - `args` (array of strings). 60 | The command line arguments that are to be passed to the Java class's main method. 61 | Same as in [child_process.spawn]. 62 | - `options` (object). Options that are passed to [child_process.spawn]. 63 | - Returns an object of the type [child_process.ChildProcess]. 64 | [child_process.spawn]: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options 65 | [child_process.ChildProcess]: https://nodejs.org/api/child_process.html#child_process_class_childprocess 66 | 67 | 68 | `jre.spawnSync(classpath, classname[, args][, options])` Synchronously spawns a new child process by running the main method of a given Java class. The command will not return until the spawned process ends. This is a wrapper around [child_process.spawnSync]. Please look there for further documentation. 69 | - `classpath` (array of strings). Paths to `.jar` files or directories containing `.class`files. 70 | - `classname` (string). The Java class to run. 71 | - `args` (array of strings). 72 | The command line arguments that are to be passed to the Java class's main method. 73 | Same as in [child_process.spawnSync]. 74 | - `options` (object). Options that are passed to [child_process.spawnSync]. 75 | - Returns a result object as in [child_process.spawnSync]. 76 | [child_process.spawnSync]: https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options 77 | 78 | ## License 79 | MIT License 80 | 81 | Copyright (c) 2016 schreiben 82 | 83 | Permission is hereby granted, free of charge, to any person obtaining a copy 84 | of this software and associated documentation files (the "Software"), to deal 85 | in the Software without restriction, including without limitation the rights 86 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 87 | copies of the Software, and to permit persons to whom the Software is 88 | furnished to do so, subject to the following conditions: 89 | 90 | The above copyright notice and this permission notice shall be included in all 91 | copies or substantial portions of the Software. 92 | 93 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 94 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 95 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 96 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 97 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 98 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 99 | SOFTWARE. 100 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* MIT License 2 | * 3 | * Copyright (c) 2016 schreiben 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | "use strict"; 25 | 26 | (function(){ 27 | 28 | const os = require('os'); 29 | const fs = require('fs'); 30 | const path = require('path'); 31 | const rimraf = require('rimraf'); 32 | const zlib = require('zlib'); 33 | const tar = require('tar-fs'); 34 | const process = require('process'); 35 | const request = require('request'); 36 | const ProgressBar = require('progress'); 37 | const child_process = require('child_process'); 38 | 39 | const major_version = '8'; 40 | const update_number = '131'; 41 | const build_number = '11'; 42 | const hash = 'd54c1d3a095b4ff2b6607d096fa80163'; 43 | const version = major_version + 'u' + update_number; 44 | 45 | const jreDir = exports.jreDir = () => path.join(__dirname, 'jre'); 46 | 47 | const fail = reason => { 48 | console.error(reason); 49 | process.exit(1); 50 | }; 51 | 52 | var _arch = os.arch(); 53 | switch (_arch) { 54 | case 'x64': break; 55 | case 'ia32': _arch = 'i586'; break; 56 | default: 57 | fail('unsupported architecture: ' + _arch); 58 | } 59 | const arch = exports.arch = () => _arch; 60 | 61 | var _platform = os.platform(); 62 | var _driver; 63 | switch (_platform) { 64 | case 'darwin': _platform = 'macosx'; _driver = ['Contents', 'Home', 'bin', 'java']; break; 65 | case 'win32': _platform = 'windows'; _driver = ['bin', 'javaw.exe']; break; 66 | case 'linux': _driver = ['bin', 'java']; break; 67 | default: 68 | fail('unsupported platform: ' + _platform); 69 | } 70 | const platform = exports.platform = () => _platform; 71 | 72 | const getDirectories = dirPath => fs.readdirSync(dirPath).filter( 73 | file => fs.statSync(path.join(dirPath, file)).isDirectory() 74 | ); 75 | 76 | const driver = exports.driver = () => { 77 | var jreDirs = getDirectories(jreDir()); 78 | if (jreDirs.length < 1) 79 | fail('no jre found in archive'); 80 | var d = _driver.slice(); 81 | d.unshift(jreDirs[0]); 82 | d.unshift(jreDir()); 83 | return path.join.apply(path, d); 84 | }; 85 | 86 | const getArgs = exports.getArgs = (classpath, classname, args) => { 87 | args = (args || []).slice(); 88 | classpath = classpath || []; 89 | args.unshift(classname); 90 | args.unshift(classpath.join(platform() === 'windows' ? ';' : ':')); 91 | args.unshift('-cp'); 92 | return args; 93 | }; 94 | 95 | const spawn = exports.spawn = 96 | (classpath, classname, args, options) => 97 | child_process.spawn(driver(), getArgs(classpath, classname, args), options); 98 | 99 | const spawnSync = exports.spawnSync = 100 | (classpath, classname, args, options) => 101 | child_process.spawnSync(driver(), getArgs(classpath, classname, args), options); 102 | 103 | const smoketest = exports.smoketest = () => 104 | spawnSync(['resources'], 'Smoketest', [], { encoding: 'utf8' }) 105 | .stdout.trim() === 'No smoke!'; 106 | 107 | const url = exports.url = () => 108 | 'https://download.oracle.com/otn-pub/java/jdk/' + 109 | version + '-b' + build_number + '/' + hash + 110 | '/jre-' + version + '-' + platform() + '-' + arch() + '.tar.gz'; 111 | 112 | const install = exports.install = callback => { 113 | var urlStr = url(); 114 | console.log("Downloading from: ", urlStr); 115 | callback = callback || (() => {}); 116 | rimraf.sync(jreDir()); 117 | request 118 | .get({ 119 | url: url(), 120 | rejectUnauthorized: false, 121 | agent: false, 122 | headers: { 123 | connection: 'keep-alive', 124 | 'Cookie': 'gpw_e24=http://www.oracle.com/; oraclelicense=accept-securebackup-cookie' 125 | } 126 | }) 127 | .on('response', res => { 128 | var len = parseInt(res.headers['content-length'], 10); 129 | var bar = new ProgressBar(' downloading and preparing JRE [:bar] :percent :etas', { 130 | complete: '=', 131 | incomplete: ' ', 132 | width: 80, 133 | total: len 134 | }); 135 | res.on('data', chunk => bar.tick(chunk.length)); 136 | }) 137 | .on('error', err => { 138 | console.log(`problem with request: ${err.message}`); 139 | callback(err); 140 | }) 141 | .on('end', () => { 142 | try{ 143 | if (smoketest()) callback(); else callback("Smoketest failed."); 144 | }catch(err){ 145 | callback(err); 146 | } 147 | }) 148 | .pipe(zlib.createUnzip()) 149 | .pipe(tar.extract(jreDir())); 150 | }; 151 | 152 | })(); 153 | --------------------------------------------------------------------------------