Browse files

Improved startup and auto-detection of Erlang environment.

Erlang env is searched for in:
 -root arg
 <classpath>
 $PATH (searching for 'erl')

ERTS and OTP versions are detected automatically.

Also, loading Erlang environment from class path now works correctly
  • Loading branch information...
1 parent f437f8f commit 1abbec5fb60ad26779f9e3c118146da632989197 @jetztgradnet jetztgradnet committed Apr 14, 2012
View
8 ej
@@ -7,23 +7,15 @@ EJ_CMD=`which "$0"`
while LINK=`readlink "$EJ_CMD"`; do EJ_CMD=$LINK; done
ERJANG_DIR=`dirname "$EJ_CMD"`
-source "$ERJANG_DIR/env_cfg"
-
## -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8787,server=n,suspend=n \
exec java \
-server \
-Xmx1g -Xss50m \
-XX:PermSize=128m \
- -Derjang.configfile="$PROP_FILE" \
- -Derjang.erts.version="$ERTS_VSN" \
- -Derjang.otp.version="$OTP_VSN" \
-jar $ERJANG_DIR/erjang-0.1.jar \
\
-progname ej \
- -home "$HOME" \
- -root "$ERL_ROOT" \
+A 10 \
+S 1 \
- +e "$ERTS_VSN" \
"$@"
View
6 erjang_cfg.properties
@@ -1,6 +1,6 @@
-erjang.otp.root = /usr/local/lib/erlang
-erjang.erts.version = 5.8.3
-erjang.otp.version = R14B02
+#erjang.otp.root = /usr/local/lib/erlang
+#erjang.erts.version = 5.8.3
+#erjang.otp.version = R14B02
# erjang.debug.port=true
# erjang.debug.inet=true
View
14 src/main/java/erjang/ERT.java
@@ -1141,4 +1141,18 @@ public void write(byte[] b, int off, int len) throws IOException {
}
}
+ /**
+ * contains versions, paths and other information.
+ * use {@link ERT#setRuntimeInfo(RuntimeInfo)} to set this field.
+ */
+ public static RuntimeInfo runtime_info = null;
+
+ public static void setRuntimeInfo(RuntimeInfo info) {
+ // TODO perform synchronization? We usually set this
+ // field only once from Main before ERT is started
+ runtime_info = info;
+ if (runtime_info != null) {
+ System.setProperty("erjang.path", runtime_info.erl_bootstrap_ebindir);
+ }
+ }
}
View
4 src/main/java/erjang/ErjangConfig.java
@@ -36,9 +36,9 @@
static {
String configFileName = System.getProperty("erjang.configfile");
- if (configFileName != null) {
+ if (configFileName != null && configFileName.trim().length() > 0) {
try {
- FileInputStream in = new FileInputStream(configFileName);
+ FileInputStream in = new FileInputStream(configFileName.trim());
try {
Properties properties = new Properties();
properties.load(in);
View
196 src/main/java/erjang/Main.java
@@ -18,171 +18,16 @@
package erjang;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileReader;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import erjang.driver.efile.EFile;
public class Main {
public static final String SYSTEM_ARCHITECTURE = "java";
public static final String DRIVER_VERSION = "1.5";
-
- // determine dynamically from $OTPROOT (and make therefore non-final), if unspecified
- public static String otp_version = (ErjangConfig.hasString("erjang.otp.version") ? ErjangConfig.getString("erjang.otp.version", null) : null);
- static String erts_version = (ErjangConfig.hasString("erjang.erts.version") ? "erts-"+ErjangConfig.getString("erjang.erts.version", null) : null);
- static String erl_rootdir;
- static String erl_bootstrap_ebindir;
-
- public static String erts_version() {
- return erts_version;
- }
-
- static String setup(String cmd_line_root) {
-
- erl_rootdir = cmd_line_root;
- if (cmd_line_root == null)
- erl_rootdir = System.getenv("OTPROOT");
-
- if (erl_rootdir == null) {
- erl_rootdir = guess_erl_root();
- }
-
- File erlangRoot = new File(erl_rootdir);
- if (!erlangRoot.isDirectory()) {
- return null;
- }
-
- if (erts_version == null) {
- // guess erts version from directory $OTPROOT/lib/erts-<version>
- File libDir = new File(erlangRoot, "lib");
- String[] ertsDirs = libDir.list(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.startsWith("erts-");
- }
- });
- if (ertsDirs != null) {
- for (int d = 0; d < ertsDirs.length; d++) {
- String dir = ertsDirs[d];
- erts_version = dir;
- }
- }
- }
-
- if (otp_version == null) {
- // guess OTP version from directory $OTPROOT/bin/start.script
- File startScript = new File(erlangRoot, "bin/start.script");
- otp_version = guess_otp_version(startScript);
- }
-
- if (otp_version == null) {
- // guess OTP version from directory $OTPROOT/bin/start.script
- File startScript = new File(erlangRoot, "releases/RELEASES");
- otp_version = guess_otp_version(startScript);
- }
-
- if (otp_version == null) {
- ERT.log.severe("Cannot determine OTP version! Please specify system property 'erjang.otp.version'");
- return null;
- }
-
- erl_bootstrap_ebindir = System.getenv("ERL_BOOTSTRAP_EBIN");
- if (erl_bootstrap_ebindir == null) {
- erl_bootstrap_ebindir = erl_rootdir + File.separator + "lib" + File.separator
- + erts_version + File.separator + "ebin";
- }
-
- return erl_rootdir;
- }
-
- private static String guess_otp_version(File file) {
- if ((file == null) || !file.exists() || !file.canRead()) {
- return null;
- }
-
- BufferedReader reader = null;
- try {
- Pattern pattern = Pattern.compile(".*\"(.*OTP[\\s]+APN.*)\",\"(R\\w+)\".*");
- reader = new BufferedReader(new FileReader(file));
- String line;
- while ((line = reader.readLine()) != null) {
- Matcher match = pattern.matcher(line);
- if (!match.matches()) {
- continue;
- }
- String otpVersion = match.group(2);
- if ((otpVersion != null)
- && (otpVersion.length() > 0)) {
- return otpVersion;
- }
- }
-
- }
- catch (Throwable t) {
- // ignore
- }
- finally {
- // close reader
- if (reader != null) {
- try {
- reader.close();
- }
- catch (Throwable t) {
- // ignore
- }
- }
- }
-
- return null;
- }
- private static String guess_erl_root() {
-
- if (Main.class.getClassLoader().getResource("bin/start.boot") != null) {
- return EFile.RESOURCE_PREFIX.substring(0, EFile.RESOURCE_PREFIX.length()-1);
- }
-
- // this logic works on Unixes ... what about windows?
- String path = System.getenv("PATH");
- List<String> paths = new ArrayList<String>();
- paths.addAll(Arrays.asList(path.split(File.pathSeparator)));
- // also check canonical locations /usr/local/lib/erlang and
- // /opt/local/lib/erlang
- paths.add("/usr/local/lib/erlang/bin");
- paths.add("/opt/local/lib/erlang/bin");
- for (String elem : paths) {
- File dir = new File(elem);
- // TODO check for some other file, which might not be s
- // symbolic link in a generic bin dir such as /usr/local/bin
- File erl = new File(dir, "erl");
- if (erl.exists()) {
-
- if (dir.getParent() == null)
- continue;
-
- File lib = new File (dir.getParent(), "lib");
- File root = new File(lib, "erlang");
-
- if (root.exists()) {
- return root.getAbsolutePath();
- }
-
- }
- }
-
- ERT.log.severe("Cannot find OTPROOT directory\n"
- + "Pass -root <dir>, or set environment variable.");
-
- return null;
- }
/**
* @param args
@@ -197,6 +42,8 @@ public static void main(String[] args) throws Exception {
ArrayList<String> ra = new ArrayList<String>();
String cmd_line_root = null;
+ String otp_version = (ErjangConfig.hasString("erjang.otp.version") ? ErjangConfig.getString("erjang.otp.version", null) : null);
+ String erts_version = (ErjangConfig.hasString("erjang.erts.version") ? "erts-"+ErjangConfig.getString("erjang.erts.version", null) : null);
for (int i = 0; i < args.length; i++) {
if ("-root".equals(args[i]) && i < args.length) {
cmd_line_root = args[i+1];
@@ -207,13 +54,22 @@ public static void main(String[] args) throws Exception {
}
}
- String root = setup(cmd_line_root);
-
- if (cmd_line_root == null) {
- ra.add("-root");
- ra.add(root);
+ RuntimeInfo runtimeInfo = RuntimeInfo.setup(erts_version, otp_version, cmd_line_root);
+ try {
+ // verify we have a working configuration
+ runtimeInfo.verify();
+ }
+ catch (RuntimeException e) {
+ String reason = e.getMessage();
+ ERT.log.severe(reason);
+ System.err.println(reason);
+ return;
}
+ String root = runtimeInfo.erl_rootdir;
+ ra.add("-root");
+ ra.add(root);
+
arg_loop:
for (int i = 0; i < args.length; i++) {
String arg = args[i];
@@ -225,6 +81,12 @@ public static void main(String[] args) throws Exception {
break;
}
+ if ("-root".equals(args[i]) && i < args.length) {
+ // skip "-root <dir>" arg, was set above
+ i++;
+ continue;
+ }
+
if (arg.startsWith("+")) {
switch (arg.charAt(1)) {
case 'a':
@@ -253,14 +115,18 @@ public static void main(String[] args) throws Exception {
ra.add(arg);
}
- System.setProperty("erjang.path", erl_bootstrap_ebindir);
+ if (!ra.contains("-home")) {
+ ra.add("-home");
+ ra.add(System.getProperty("user.home"));
+ }
+
+ ERT.setRuntimeInfo(runtimeInfo);
- if (!(new File(erl_bootstrap_ebindir)).exists() && !erl_bootstrap_ebindir.startsWith(EFile.RESOURCE_PREFIX)) {
- ERT.log.severe("No bootstrap classes at: "+erl_bootstrap_ebindir);
- throw new IllegalArgumentException("No bootstrap classes at: "+erl_bootstrap_ebindir);
+ if (!(new File(runtimeInfo.erl_bootstrap_ebindir)).exists() && !runtimeInfo.erl_bootstrap_ebindir.startsWith(EFile.RESOURCE_PREFIX)) {
+ ERT.log.severe("No bootstrap classes at: "+runtimeInfo.erl_bootstrap_ebindir);
+ throw new IllegalArgumentException("No bootstrap classes at: "+runtimeInfo.erl_bootstrap_ebindir);
}
OTPMain.main(ra.toArray(new String[ra.size()]));
}
-
}
View
60 src/main/java/erjang/OTPMain.java
@@ -21,6 +21,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
@@ -50,31 +51,33 @@
new erjang.driver.js.EJSDriver()
};
- public static void load_modules_and_drivers() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
-
- if (Main.erl_bootstrap_ebindir.startsWith(EFile.RESOURCE_PREFIX)) {
-
- for (String m : MODULES) {
- String beam_path = Main.erl_bootstrap_ebindir + "/" + m + ".beam";
- EBinary bin = ClassPathResource.read_file(beam_path);
- if (bin == null) {
- throw new FileNotFoundException(beam_path);
+ public static void load_modules_and_drivers(List<String> modules, List<EDriver> drivers) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
+
+ if (modules != null) {
+ String erl_bootstrap_ebindir = ERT.runtime_info.erl_bootstrap_ebindir;
+ if (ClassPathResource.isResource(erl_bootstrap_ebindir)) {
+
+ for (String m : modules) {
+ String beam_path = erl_bootstrap_ebindir + "/" + m + ".beam";
+ EBinary bin = ClassPathResource.read_file(beam_path);
+ if (bin == null) {
+ throw new FileNotFoundException(beam_path);
+ }
+ EModuleLoader.load_module(m, bin);
}
- EModuleLoader.load_module(m, bin);
- }
-
- } else {
- for (String m : MODULES) {
- ERT.load_module(EAtom.intern(m));
- }
+
+ } else {
+ for (String m : modules) {
+ ERT.load_module(EAtom.intern(m));
+ }
+ }
}
- for (EDriver d : DRIVERS) {
- erjang.driver.Drivers.register(d);
- }
- for (EDriver d : extra_drivers) {
- erjang.driver.Drivers.register(d);
- }
+ if (drivers != null) {
+ for (EDriver d : drivers) {
+ erjang.driver.Drivers.register(d);
+ }
+ }
}
public static void start_otp_ring0(ESeq argv) {
@@ -111,6 +114,14 @@ protected static ESeq process_args(String[] args) {
return argv;
}
+ /**
+ * {@link ERT#setRuntimeInfo(RuntimeInfo)} should have been called, before calling this method
+ * @param args
+ * @throws ClassNotFoundException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws IOException
+ */
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
ESeq argv = process_args(args);
@@ -119,10 +130,11 @@ public static void main(String[] args) throws ClassNotFoundException, Instantiat
// Logger.getLogger("erjang").setLevel(Level.FINE);
// Logger.getLogger("kilim.Task").setLevel(Level.FINEST);
- load_modules_and_drivers();
+ load_modules_and_drivers(Arrays.asList(MODULES), Arrays.asList(DRIVERS));
+ load_modules_and_drivers(null, extra_drivers);
start_otp_ring0(argv);
- System.out.println("done.");
+ ERT.getOutputStream().println("done.");
}
static List<EDriver> extra_drivers = new ArrayList<EDriver>();
View
330 src/main/java/erjang/RuntimeInfo.java
@@ -0,0 +1,330 @@
+/**
+ * This file is part of Erjang - A JVM-based Erlang VM
+ *
+ * Copyright (c) 2010 by Wolfgang Schell
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+package erjang;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import erjang.driver.efile.ClassPathResource;
+import erjang.driver.efile.EFile;
+
+/**
+ * Holder of runtime information such as Erlang and OTP version,
+ * root path, etc.
+ *
+ * @author jetztgradnet
+ */
+public class RuntimeInfo {
+ public final String erts_version;
+ public final String otp_version;
+ public final String erl_rootdir;
+ public final String erl_bootstrap_ebindir;
+
+ /**
+ * the new unicode driver interface is used since OTP version R14B01.
+ *
+ * @see http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id60205
+ */
+ public final boolean unicodeDriverInterface;
+
+ public RuntimeInfo(String erts_version, String otp_version, String erl_rootdir, String erl_bootstrap_ebindir) {
+ this.erts_version = erts_version;
+ this.otp_version = otp_version;
+ this.erl_rootdir = erl_rootdir;
+ this.erl_bootstrap_ebindir = erl_bootstrap_ebindir;
+
+ if (otp_version != null) {
+ unicodeDriverInterface = ("R14B".compareTo(otp_version) < 0);
+ }
+ else {
+ unicodeDriverInterface = false;
+ }
+ }
+
+ public void verify() throws RuntimeException {
+ if (isNullOrEmpty(erl_rootdir)) {
+ throw new RuntimeException("Erlang runtime not found, please specify root directory using parameter '-root <OTP_ROOT>'");
+ }
+
+ if (isNullOrEmpty(erts_version)) {
+ throw new RuntimeException("Cannot determine ERTS version! Please specify system property 'erjang.erts.version'");
+ }
+
+ if (isNullOrEmpty(otp_version)) {
+ throw new RuntimeException("Cannot determine OTP version! Please specify system property 'erjang.otp.version'");
+ }
+ }
+
+ public boolean isClassPathInstallation() {
+ return isClassPathInstallation(erl_rootdir);
+ }
+
+ public static boolean isClassPathInstallation(String erl_rootdir) {
+ return ClassPathResource.isResource(erl_rootdir);
+ }
+
+ protected static final String ERLANG_RELEASESTARTFILE = "releases/start_erl.data";
+ protected static final String ERLANG_RELEASEFILE = "releases/RELEASES";
+ protected static final String ERLANG_STARTSCRIPT = "bin/start.script";
+ protected static final String ERLANG_BOOTFILE = "bin/start.boot";
+ protected static final String ERLANG_STARTSCRIPT_REGEX = ".*\".*OTP[\\s]+APN.*\",\"(R\\w+)\".*";
+ protected static final String ERLANG_RELEASEFILE_REGEX = ".*\".*OTP[\\s]+APN.*\",\"(R\\w+)\",\"([0-9]\\.[0-9]\\.[0-9])\".*";
+ protected static final String ERLANG_RELEASESTARTFILE_REGEX = "(\\S+)\\s+(\\S+)";
+
+ // determine dynamically from $OTPROOT (and make therefore non-final), if unspecified
+
+ public static RuntimeInfo setup(String erts_version, String otp_version, String erl_rootdir) {
+ if (isNullOrEmpty(erl_rootdir)) {
+ erl_rootdir = guess_erl_root();
+ }
+ if (!isNullOrEmpty(erl_rootdir)) {
+ if (erl_rootdir.endsWith("/") || erl_rootdir.endsWith("\\")) {
+ erl_rootdir = erl_rootdir.substring(0, erl_rootdir.length() - 1);
+ }
+ }
+
+ if (isNullOrEmpty(erts_version)) {
+ erts_version = guess_erts_version(erl_rootdir);
+ }
+
+ if (isNullOrEmpty(otp_version)) {
+ otp_version = guess_otp_version(erl_rootdir);
+ }
+
+ String erl_bootstrap_ebindir = System.getenv("ERL_BOOTSTRAP_EBIN");
+ if (isNullOrEmpty(erl_bootstrap_ebindir)) {
+ erl_bootstrap_ebindir = erl_rootdir;
+ if (!erl_bootstrap_ebindir.endsWith("/") && !erl_bootstrap_ebindir.endsWith("\\")) {
+ erl_bootstrap_ebindir += File.separator;
+ }
+ erl_bootstrap_ebindir += "lib" + File.separator + "erts-" + erts_version + File.separator + "ebin";
+ }
+
+ return new RuntimeInfo(erts_version, otp_version, erl_rootdir, erl_bootstrap_ebindir);
+ }
+
+ public static String guess_otp_version(String erl_rootdir) {
+ // guess OTP version from directory $OTPROOT/releases/RELEASES
+ String otp_version = guess_version(ERLANG_RELEASESTARTFILE_REGEX, 2, erl_rootdir, ERLANG_RELEASESTARTFILE);
+ if (isNullOrEmpty(otp_version)) {
+ otp_version = guess_version(ERLANG_RELEASEFILE_REGEX, 1, erl_rootdir, ERLANG_RELEASEFILE);
+ }
+ if (isNullOrEmpty(otp_version)) {
+ // fallback: guess OTP version from directory $OTPROOT/bin/start.script
+ otp_version = guess_version(ERLANG_STARTSCRIPT_REGEX, 1, erl_rootdir, ERLANG_STARTSCRIPT);
+ }
+
+ return otp_version;
+ }
+
+ public static String guess_erts_version(String erl_rootdir) {
+ // guess ERTS version from directory $OTPROOT/releases/RELEASES
+ String erts_version = guess_version(ERLANG_RELEASESTARTFILE_REGEX, 1, erl_rootdir, ERLANG_RELEASESTARTFILE);
+ if (isNullOrEmpty(erts_version)) {
+ erts_version = guess_version(ERLANG_RELEASEFILE_REGEX, 2, erl_rootdir, ERLANG_RELEASEFILE);
+ }
+ if (isNullOrEmpty(erts_version)) {
+ // fallback: guess ERTS version from erts directory
+ File erlangRoot = new File(erl_rootdir);
+ if (erlangRoot.isDirectory()) {
+ // guess erts version from directory $OTPROOT/lib/erts-<version>
+ File libDir = new File(erlangRoot, "lib");
+ String[] ertsDirs = libDir.list(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith("erts-");
+ }
+ });
+ if (ertsDirs != null) {
+ for (int d = 0; d < ertsDirs.length; d++) {
+ String dir = ertsDirs[d];
+ erts_version = dir;
+ }
+ }
+ }
+ }
+ return erts_version;
+ }
+
+ protected static String guess_version(String regex, int group, String erl_rootdir, String fileName) {
+ if (isNullOrEmpty(erl_rootdir) || RuntimeInfo.isClassPathInstallation(erl_rootdir)) {
+ return guess_version_from_resource(regex, group, fileName);
+ }
+ File erlangRoot = new File(erl_rootdir);
+ if (erlangRoot.isDirectory()) {
+ return guess_version_from_file(regex, group, new File(erlangRoot, fileName));
+ }
+ else {
+ return guess_version_from_resource(regex, group, fileName);
+ }
+ }
+
+ protected static String guess_version_from_resource(String regex, int group, String fileName) {
+ InputStream input = null;
+
+ try {
+ input = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
+ return guess_version_from_reader(regex, group, new InputStreamReader(input));
+ }
+ catch (Throwable t) {
+ // ignore
+ }
+ finally {
+ // close reader
+ closeQuietly(input);
+ }
+
+ return null;
+ }
+
+ protected static String guess_version_from_file(String regex, int group, File file) {
+ if ((file == null) || !file.exists() || !file.canRead()) {
+ return null;
+ }
+
+ FileReader reader = null;
+ try {
+ reader = new FileReader(file);
+ return guess_version_from_reader(regex, group, reader);
+ }
+ catch (Throwable t) {
+ // ignore
+ }
+ finally {
+ // close reader
+ closeQuietly(reader);
+ }
+
+ return null;
+ }
+
+ protected static String guess_version_from_reader(String regex, int group, Reader input) {
+ BufferedReader reader = null;
+ try {
+ Pattern pattern = Pattern.compile(regex);
+ reader = new BufferedReader(input);
+ String line;
+ while ((line = reader.readLine()) != null) {
+ Matcher match = pattern.matcher(line);
+ if (!match.matches()) {
+ continue;
+ }
+ String versionString = match.group(group);
+ if ((versionString != null)
+ && (versionString.length() > 0)) {
+ return versionString.trim();
+ }
+ }
+ }
+ catch (Throwable t) {
+ // ignore
+ }
+ finally {
+ // close reader
+ closeQuietly(reader);
+ }
+
+ return null;
+ }
+
+ protected static boolean isNullOrEmpty(String text) {
+ if (text == null || text.trim().length() == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ public static String guess_erl_root() {
+
+ String erl_rootdir = System.getenv("OTPROOT");
+
+ if (isNullOrEmpty(erl_rootdir)) {
+ // check whether we have Erlang/OTP on the classpath
+ if (Thread.currentThread().getContextClassLoader().getResource(ERLANG_BOOTFILE) != null) {
+ erl_rootdir = EFile.RESOURCE_PREFIX;
+ }
+ }
+
+ if (isNullOrEmpty(erl_rootdir)) {
+ // discover Erlang from $PATH
+ // this logic works on Unixes ... what about windows?
+ String path = System.getenv("PATH");
+ List<String> paths = new ArrayList<String>();
+ paths.addAll(Arrays.asList(path.split(File.pathSeparator)));
+ // also check canonical locations /usr/local/lib/erlang and
+ // /opt/local/lib/erlang
+ paths.add("/usr/local/lib/erlang/bin");
+ paths.add("/opt/local/lib/erlang/bin");
+ for (String elem : paths) {
+ File dir = new File(elem);
+ // TODO check for some other file, which might not be a
+ // symbolic link in a generic bin dir such as /usr/local/bin
+ File erl = new File(dir, "erl");
+ if (erl.exists()) {
+ File baseDir = dir.getParentFile();
+ if (baseDir == null)
+ continue;
+
+ // check for <basedir>/releases
+ File releases = new File(baseDir, "releases");
+ if (releases.isDirectory()) {
+ erl_rootdir = baseDir.getAbsolutePath();
+ break;
+ }
+
+
+ // check for <basedir>/lib/erlang
+ // (Unix-style installation with Erlang bin living next to lib/erlang)
+ File lib = new File (baseDir, "lib");
+ File root = new File(lib, "erlang");
+
+ if (root.exists()) {
+ erl_rootdir = root.getAbsolutePath();
+ break;
+ }
+ }
+ }
+ }
+
+ return erl_rootdir;
+ }
+
+ protected static void closeQuietly(Closeable stream) {
+ if (stream != null) {
+ try {
+ stream.close();
+ }
+ catch (Throwable t) {
+ // ignore
+ }
+ }
+ }
+
+}
View
29 src/main/java/erjang/driver/efile/ClassPathResource.java
@@ -19,15 +19,34 @@
import erjang.driver.IO;
public class ClassPathResource {
+ public static boolean isResource(String fileName) {
+ return fileName.startsWith(EFile.RESOURCE_PREFIX);
+ }
+ public static String getResourceName(String fileName) {
+ if (!isResource(fileName))
+ return fileName;
+
+ fileName = fileName.substring(EFile.RESOURCE_PREFIX.length());
+ if (fileName.startsWith(File.separator) || fileName.startsWith("/")) {
+ fileName = fileName.substring(1);
+ }
+
+ return fileName;
+ }
public static EBinary read_file(String name) {
if (!name.startsWith(EFile.RESOURCE_PREFIX))
return null;
-
+
+ String fileName = getResourceName(name);
InputStream resource = ClassPathResource.class.getClassLoader()
- .getResourceAsStream(
- name.substring(EFile.RESOURCE_PREFIX.length()));
+ .getResourceAsStream(fileName);
+ if (resource == null) {
+ // fallback: check context class loader
+ resource = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(fileName);
+ }
if (resource == null) {
return null;
@@ -196,8 +215,8 @@ private static void put_time(ByteBuffer res, long time) {
}
static ZipEntry get_entry(String path) throws IOException {
- Enumeration<URL> out = ClassPathResource.class.getClassLoader()
- .getResources(path.substring(EFile.RESOURCE_PREFIX.length()));
+ String fileName = getResourceName(path);
+ Enumeration<URL> out = ClassPathResource.class.getClassLoader().getResources(fileName);
while (out.hasMoreElements()) {
URL u = out.nextElement();
View
14 src/main/java/erjang/driver/efile/EFile.java
@@ -795,8 +795,7 @@ public void ready() throws Pausable {
return;
}
- if (name.startsWith(RESOURCE_PREFIX)) {
-
+ if (ClassPathResource.isResource(name)) {
EBinary data = ClassPathResource.read_file(name);
if (data == null) {
reply_posix_error(Posix.ENOENT);
@@ -1516,7 +1515,7 @@ public void ready() throws Pausable {
final String file_name = IO.strcpy(buf);
final File file = ERT.newFile(file_name);
- if (file_name.startsWith(RESOURCE_PREFIX)) {
+ if (ClassPathResource.isResource(file_name)) {
ClassPathResource.fstat(this, file_name);
return;
}
@@ -1961,13 +1960,6 @@ void reply_list_directory(String[] files) throws Pausable {
}
/**
- * the new unicode driver interface is used since OTP version R14B01.
- *
- * @see http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id60205
- */
- static boolean unicodeDriverInterface = ("R14B".compareTo(erjang.Main.otp_version == null ? "" : erjang.Main.otp_version) < 0);
-
- /**
* Determine whether to use the new unicode driver interface
* from R14B01.
*
@@ -1978,6 +1970,6 @@ void reply_list_directory(String[] files) throws Pausable {
* @see http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id60205
*/
private static boolean isUnicodeDriverInterface() {
- return unicodeDriverInterface;
+ return ERT.runtime_info.unicodeDriverInterface;
}
}
View
23 src/main/java/erjang/m/erlang/ErlProc.java
@@ -34,7 +34,6 @@
import erjang.ECons;
import erjang.EFun;
import erjang.EHandle;
-import erjang.EInternalPID;
import erjang.EModuleManager;
import erjang.EObject;
import erjang.EPID;
@@ -57,7 +56,6 @@
import erjang.Import;
import erjang.Main;
import erjang.NotImplemented;
-import erjang.OTPMain;
/**
*
@@ -300,7 +298,7 @@ public static EObject halt(EProc proc, EObject value) {
}
ERT.shutdown();
- throw new erjang.ErlangHalt();
+ throw new ErlangHalt();
}
@BIF
@@ -412,10 +410,10 @@ static public EObject demonitor(EProc self, EObject ref) throws Pausable {
*/
@BIF
static public EObject demonitor(EProc self, EObject ref, EObject options) throws Pausable {
- return demonitor((ETask)self, ref, options);
+ return demonitor((ETask<?>)self, ref, options);
}
- static public EObject demonitor(ETask self, EObject ref, EObject options) throws Pausable {
+ static public EObject demonitor(ETask<?> self, EObject ref, EObject options) throws Pausable {
ERef r = ref.testReference();
ESeq o = options.testSeq();
@@ -582,7 +580,6 @@ static EObject system_info(EProc proc, EObject type) {
return ERT.TRUE;
} else if (type == am_thread_pool_size) {
-
// TODO: hook up to thread pool
return new ESmall(ERT.threadPoolSize());
@@ -598,12 +595,16 @@ static EObject system_info(EProc proc, EObject type) {
return ERT.TRUE;
} else if (type == am_version) {
- return EString.fromString( erjang.Main.erts_version().substring("erts-".length()) );
+ String erts_version = ERT.runtime_info.erts_version;
+ // remove prefix
+ String prefix = "erts-";
+ if (erts_version.startsWith(prefix)) {
+ erts_version = erts_version.substring(prefix.length());
+ }
+ return EString.fromString(erts_version);
} else if (type == am_otp_release) {
- // TODO: be smarter somehow
- return new EString(Main.otp_version);
-
+ return new EString(ERT.runtime_info.otp_version);
} else if (type == am_logical_processors) {
// TODO: be smarter somehow
return ERT.box(Runtime.getRuntime().availableProcessors());
@@ -631,7 +632,7 @@ static EObject system_info(EProc proc, EObject type) {
return am_undefined;
} else if (type == am_system_version) {
- return new EString("Erjang ["+ erjang.Main.erts_version()+"]");
+ return new EString("Erjang ["+ ERT.runtime_info.erts_version+"]");
} else if ((tup=ETuple2.cast(type)) != null) {

0 comments on commit 1abbec5

Please sign in to comment.