Skip to content

Commit

Permalink
Support building self-contained Erjang+OTP jar file
Browse files Browse the repository at this point in the history
Usage: Edit the file erjang_cfg.properties `erjang.otp.root` and make 
it point to an R13-based release before running `ant jar otpjar`.

Remember, Erjang does not work with R14-based releases yet,
because the file driver changed API and we've not updated that.

The current code in ClassPathResource.java is ugly and slow:
implementation of `file:list_dir/1` iterate through the entire classpath.
... and `file:file_info/1` opens the .jar every time it is called.
Should maybe cache some directory-like structure, but those are 
really only called during boot so be careful to cache for too long.
  • Loading branch information
krestenkrab committed May 24, 2011
1 parent 9b3148f commit 4d194ef
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 20 deletions.
23 changes: 23 additions & 0 deletions build.xml
@@ -1,6 +1,8 @@
<?xml version="1.0"?>
<project name="erjang" default="all">
<property name="erjang.version" value="0.1" />
<property file="erjang_cfg.properties" />

<path id="erjang.classpath">
<pathelement location="target/classes/" />
<pathelement location="lib/js.jar" />
Expand Down Expand Up @@ -178,6 +180,27 @@
</jar>
</target>

<target name="otpjar">
<jar jarfile="otp-${erjang.otp.version}.jar" basedir="${erjang.otp.root}">
<exclude name="**/*.so" />
<exclude name="**/*.dll" />
<exclude name="**/*.a" />
<exclude name="**/*.erl" />
<exclude name="**/bin/beam" />
<exclude name="**/bin/beam.smp" />
<exclude name="lib/megaco-*/**" />
<exclude name="lib/wx-*/**" />
<exclude name="lib/hipe-*/**" />
<exclude name="lib/jinterface-*/**" />

<!-- include all of erjang -->
<zipgroupfileset dir="." includes="erjang-${erjang.version}.jar" />

<manifest>
<attribute name="Main-Class" value="erjang.Main" />
</manifest>
</jar>
</target>

<target name="javadoc" description="generate Javadoc documentation">
<javadoc destdir="target/doc">
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/erjang/EModuleLoader.java
Expand Up @@ -24,6 +24,8 @@
import erjang.beam.EUtil;

import erjang.beam.loader.ErjangBeamDisLoader;
import erjang.driver.efile.ClassPathResource;
import erjang.driver.efile.EFile;

import erjang.util.Progress;

Expand Down Expand Up @@ -112,6 +114,8 @@ private static File findBeamFile(String module) {
File beam = new File(e, n + ".beam");
if (beam.exists())
return beam;
if (ClassPathResource.read_file(beam.getPath()) != null)
return beam;
}

return null;
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/erjang/Main.java
Expand Up @@ -22,6 +22,8 @@
import java.io.IOException;
import java.util.ArrayList;

import erjang.driver.efile.EFile;

public class Main {
public static final String SYSTEM_ARCHITECTURE = "java";
public static final String OTP_VERSION = ErjangConfig.getString("erjang.otp.version", "R13B04");
Expand Down Expand Up @@ -56,6 +58,10 @@ static String setup(String cmd_line_root) {

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");
for (String elem : path.split(File.pathSeparator)) {
Expand Down Expand Up @@ -154,7 +160,7 @@ public static void main(String[] args) throws Exception {

System.setProperty("erjang.path", erl_bootstrap_ebindir);

if (!(new File(erl_bootstrap_ebindir)).exists()) {
if (!(new File(erl_bootstrap_ebindir)).exists() && !erl_bootstrap_ebindir.startsWith(EFile.RESOURCE_PREFIX)) {
System.err.println("No bootstrap classes at: "+erl_bootstrap_ebindir);
System.exit(1);
}
Expand Down
24 changes: 21 additions & 3 deletions src/main/java/erjang/OTPMain.java
Expand Up @@ -18,6 +18,7 @@

package erjang;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -27,6 +28,8 @@
import java.util.logging.Logger;

import erjang.driver.EDriver;
import erjang.driver.efile.ClassPathResource;
import erjang.driver.efile.EFile;

/**
* This will eventually be the main entrypoint for an OTP node.
Expand All @@ -49,9 +52,24 @@ public class OTPMain {
};

public static void load_modules_and_drivers() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
for (String m : MODULES) {
ERT.load_module(EAtom.intern(m));
}

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);
}
EModuleLoader.load_module(m, bin);
}

} else {
for (String m : MODULES) {
ERT.load_module(EAtom.intern(m));
}
}

for (EDriver d : DRIVERS) {
erjang.driver.Drivers.register(d);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/erjang/driver/EDriverInstance.java
Expand Up @@ -136,7 +136,7 @@ protected void driver_outputv(ByteBuffer hdr, ByteBuffer[] ev) throws Pausable {
task.output_from_driver(res);
}

protected void driver_output2(ByteBuffer header, ByteBuffer buf) throws Pausable {
public void driver_output2(ByteBuffer header, ByteBuffer buf) throws Pausable {

int status = task.status;

Expand Down
28 changes: 28 additions & 0 deletions src/main/java/erjang/driver/IO.java
Expand Up @@ -20,6 +20,7 @@

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.ConnectException;
Expand All @@ -29,6 +30,7 @@
import java.nio.charset.Charset;
import java.util.zip.GZIPOutputStream;

import erjang.EBinary;
import erjang.ERT;
import erjang.driver.efile.Posix;

Expand Down Expand Up @@ -218,4 +220,30 @@ public static String getstr(ByteBuffer buf, boolean term) {
}
}

static private class BARR2 extends ByteArrayOutputStream {
EBinary asBinary() {
return new EBinary(super.buf, 0, super.count);
}
}

public static EBinary istream2binary(InputStream in) throws IOException {
BARR2 out = new BARR2();
byte[] buf = new byte[4 * 1024];
int read;
while ((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
return out.asBinary();
}

public static byte[] istream2bytearray(InputStream in) throws IOException {
BARR2 out = new BARR2();
byte[] buf = new byte[4 * 1024];
int read;
while ((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
return out.toByteArray();
}

}

0 comments on commit 4d194ef

Please sign in to comment.