Integrate our deterministic OpenJDK fork with Avian (#117)

* Remove non-deterministic classes from Avian (wip).
* Complete integration between Avian and our local OpenJDK fork.
* Revert accidental Avian modification.
* Implements a "blacklist filter" for Avian's system classloader.
* Remove .DSA, .RSA, .SF and .MF files when creating a fat jar.
* Revert more accidental Avian changes.
* Fix breakage with dependencies, and retain Kryo instance.
* Apply blacklisting per thread rather than globally.
* Blacklist java.lang.ClassLoader and all java.lang.Thread* classes.
* Add comment explaining class blacklisting.
* Fix Avian when building without OpenJDK.
* Configure ProGuard to keep more classes for deserialisation.
* Retain explicit return type for secure random function.
* Add sources of random numbers to the class blacklist.
* Blacklist the threading classes more precisely.
* Make SystemClassLoader.isForbidden() static.
* Prevent ProGuard from removing SerializedLambda.readResolve().
* Remove Avian tests involving direct buffers.
This commit is contained in:
Chris Rankin 2017-11-21 17:06:18 +00:00 committed by GitHub
parent 6a631ec626
commit 4dbd404f64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
78 changed files with 238 additions and 5088 deletions

View File

@ -219,7 +219,7 @@ private val _newSecureRandom: () -> SecureRandom by lazy {
* which should never happen and suggests an unusual JVM or non-standard Java library.
*/
@Throws(NoSuchAlgorithmException::class)
fun newSecureRandom() = _newSecureRandom()
fun newSecureRandom(): SecureRandom = _newSecureRandom()
/**
* Returns a random positive non-zero long generated using a secure RNG. This function sacrifies a bit of entropy in order

View File

@ -1,7 +1,8 @@
package net.corda.core.utilities
object SgxSupport {
@JvmStatic
val isInsideEnclave: Boolean by lazy {
System.getProperty("os.name") == "Linux" && (System.getProperty("java.vm.name") == "Avian")
(System.getProperty("os.name") == "Linux") && (System.getProperty("java.vm.name") == "Avian (Corda)")
}
}
}

View File

@ -11,7 +11,7 @@ all: jvm-enclave/standalone/build/standalone_sgx_verify linux-sgx-driver/isgx.ko
# The final binary
jvm-enclave/standalone/build/standalone_sgx_verify: avian linux-sgx/build/linux/aesm_service
JAVA_HOME=$(JAVA_HOME) $(MAKE) -C jvm-enclave
JAVA_HOME=$(JAVA_HOME) JDK_IMAGE=$(JDK_IMAGE) $(MAKE) -C jvm-enclave
# Avian with SGX support
AVIAN_EXTRA_CFLAGS="-I$(ROOT)/usr/include -I$(ROOT)/usr/include/x86_64-linux-gnu"

View File

@ -18,6 +18,9 @@ import java.util.Collections;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;
public class SystemClassLoader extends ClassLoader {
public static native ClassLoader appLoader();
@ -25,6 +28,7 @@ public class SystemClassLoader extends ClassLoader {
private native VMClass findVMClass(String name)
throws ClassNotFoundException;
@Override
protected Class findClass(String name) throws ClassNotFoundException {
return getClass(findVMClass(name));
}
@ -35,11 +39,54 @@ public class SystemClassLoader extends ClassLoader {
private native VMClass findLoadedVMClass(String name);
private static native void startBlacklisting0();
public void startBlacklisting() {
if (isForbidden("java/util/regex/Pattern$Test")) {
throw new IllegalStateException("Impossible!");
}
startBlacklisting0();
}
private static final Set<Pattern> BLACKLIST = Collections.unmodifiableSet(setOf(
Pattern.compile("^java/lang/reflect/"),
Pattern.compile("^java/lang/invoke/"),
Pattern.compile("^java/io/File"),
Pattern.compile("^java/net/"),
Pattern.compile("^java/.*Random$"),
Pattern.compile("^java/util/concurrent/"),
Pattern.compile("^java/lang/ClassLoader$"),
Pattern.compile("^java/lang/(Inheritable)?ThreadLocal$"),
Pattern.compile("^java/lang/Thread$"),
Pattern.compile("^com/sun/"),
Pattern.compile("^sun/")
));
private static <T> Set<T> setOf(T... items) {
Set<T> set = new LinkedHashSet<T>();
Collections.addAll(set, items);
return set;
}
/*
* Invoked via JNI, so uses the specification
* rather than the class name.
*/
private static boolean isForbidden(String spec) {
for (Pattern bad : BLACKLIST) {
if (bad.matcher(spec).find()) {
return true;
}
}
return false;
}
protected Class reallyFindLoadedClass(String name){
VMClass c = findLoadedVMClass(name);
return c == null ? null : getClass(c);
}
@Override
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
@ -83,6 +130,7 @@ public class SystemClassLoader extends ClassLoader {
// appropriate for the Avian build, so we override it to ensure we
// get the behavior we want. This implementation is the same as
// that of Avian's java.lang.ClassLoader.getResource.
@Override
public URL getResource(String path) {
URL url = null;
ClassLoader parent = getParent();
@ -99,6 +147,7 @@ public class SystemClassLoader extends ClassLoader {
// As above, we override this method to avoid inappropriate behavior
// in OpenJDK's java.lang.ClassLoader.getResources.
@Override
public Enumeration<URL> getResources(String name) throws IOException {
Collection<URL> urls = new ArrayList<URL>(5);

View File

@ -1,148 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian.http;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Handler extends URLStreamHandler
{
public URLConnection openConnection(URL url) throws IOException
{
return new HttpURLConnection(url);
}
class HttpURLConnection extends URLConnection
{
private static final String HKEY_CONTENT_LENGTH = "content-length";
Socket socket;
private BufferedWriter writer;
private InputStream bin;
private Map<String, List<String>> header = new HashMap<String, List<String>>();
private int status;
protected HttpURLConnection(URL url)
{
super(url);
}
@Override
public void connect() throws IOException
{
if(socket == null)
{
URLConnection con = null;
String host = url.getHost();
int port =url.getPort();
if(port < 0) port = 80;
socket = new Socket(host, port);
OutputStream out = socket.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write("GET " + url.getPath() + " HTTP/1.1");
writer.write("\r\nHost: " + host);
writer.write("\r\n\r\n");
writer.flush();
bin = new BufferedInputStream(socket.getInputStream());
readHeader();
// System.out.println("Status: " + status);
// System.out.println("Headers: " + header);
}
}
private void readHeader() throws IOException
{
byte[] buf = new byte[8192];
int b = 0;
int index = 0;
while(b >= 0)
{
if(index >= 4 && buf[index-4] == '\r' && buf[index-3] == '\n' && buf[index-2] == '\r' && buf[index-1] == '\n')
{
break;
}
b = bin.read();
buf[index] = (byte) b;
index++;
if(index >= buf.length)
{
throw new IOException("Header exceeded maximum size of 8k.");
}
}
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, index)));
String line = reader.readLine();
int x = line.indexOf(' ');
status = Integer.parseInt(line.substring(x + 1 , line.indexOf(' ', x+1)));
while(line != null)
{
int i = line.indexOf(':');
if(i > 0)
{
String key = line.substring(0, i).toLowerCase();
String value = line.substring(i + 1).trim();
List<String> valueList = new ArrayList<String>();
valueList.add(value);
header.put(key, Collections.unmodifiableList(valueList));
}
line = reader.readLine();
}
reader.close();
}
@Override
public InputStream getInputStream() throws IOException
{
connect();
return bin;
}
@Override
public OutputStream getOutputStream() throws IOException
{
throw new UnsupportedOperationException("Can' write to HTTP Connection");
}
@Override
public int getContentLength()
{
return getHeaderFieldInt(HKEY_CONTENT_LENGTH, -1);
}
@Override
public long getContentLengthLong()
{
return getHeaderFieldLong(HKEY_CONTENT_LENGTH, -1l);
}
@Override
public Map<String,List<String>> getHeaderFields()
{
return Collections.unmodifiableMap(header);
}
}
}

View File

@ -347,65 +347,6 @@ extern "C" JNIEXPORT jlong JNICALL
return 0;
}
extern "C" JNIEXPORT void JNICALL
Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
{
string_t chars = getChars(e, path);
if (chars) {
if (not exists(chars)) {
int r = ::MKDIR(chars, 0777);
if (r != 0) {
throwNewErrno(e, "java/io/IOException");
}
}
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
{
bool result = false;
string_t chars = getChars(e, path);
if (chars) {
if (not exists(chars)) {
int fd = OPEN(chars, O_CREAT | O_WRONLY | O_EXCL, 0666);
if (fd == -1) {
if (errno != EEXIST) {
throwNewErrno(e, "java/io/IOException");
}
} else {
result = true;
doClose(e, fd);
}
}
releaseChars(e, path, chars);
}
return result;
}
extern "C" JNIEXPORT void JNICALL
Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
{
string_t chars = getChars(e, path);
int r;
if (chars) {
#ifdef PLATFORM_WINDOWS
if (GetFileAttributes(chars) & FILE_ATTRIBUTE_DIRECTORY) {
r = !RemoveDirectory(chars);
} else {
r = REMOVE(chars);
}
#else
r = REMOVE(chars);
#endif
if (r != 0) {
throwNewErrno(e, "java/io/IOException");
}
releaseChars(e, path, chars);
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path)
{
@ -497,27 +438,6 @@ extern "C" JNIEXPORT jboolean JNICALL
#endif
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
{
string_t oldChars = getChars(e, old);
string_t newChars = getChars(e, new_);
if (oldChars) {
bool v;
if (newChars) {
v = RENAME(oldChars, newChars) == 0;
releaseChars(e, new_, newChars);
} else {
v = false;
}
releaseChars(e, old, oldChars);
return v;
} else {
return false;
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
{

View File

@ -376,103 +376,6 @@ void copyAndEscape(char** dest, const char* src, size_t length)
*dest = destp;
}
extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e,
jclass,
jobjectArray command,
jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i) {
jstring element = (jstring)e->GetObjectArrayElement(command, i);
if (element) {
// worst case, assuming every character is '"', and we escape all of them
size += 2 * e->GetStringUTFLength(element) + 3;
} else {
throwNew(e,
"java/lang/NullPointerException",
strdup("null string array element"));
}
}
RUNTIME_ARRAY(char, line, size);
char* linep = RUNTIME_ARRAY_BODY(line);
for (int i = 0; i < e->GetArrayLength(command); ++i) {
if (i)
*(linep++) = _T(' ');
jstring element = (jstring)e->GetObjectArrayElement(command, i);
const char* s = e->GetStringUTFChars(element, 0);
copyAndEscape(&linep, s, e->GetStringUTFLength(element));
e->ReleaseStringUTFChars(element, s);
}
*(linep++) = _T('\0');
HANDLE in[] = {0, 0};
HANDLE out[] = {0, 0};
HANDLE err[] = {0, 0};
makePipe(e, in);
SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
makePipe(e, out);
SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
makePipe(e, err);
SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
if (e->ExceptionCheck())
return;
e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = in[1];
si.hStdInput = out[0];
si.hStdError = err[1];
BOOL success = CreateProcess(0,
(LPSTR)RUNTIME_ARRAY_BODY(line),
0,
0,
1,
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
0,
0,
&si,
&pi);
CloseHandle(in[1]);
CloseHandle(out[0]);
CloseHandle(err[1]);
if (not success) {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
return;
}
jlong pid = reinterpret_cast<jlong>(pi.hProcess);
e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
@ -1003,60 +906,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL
return array;
}
// System.getEnvironment() implementation
// TODO: For Win32, replace usage of deprecated _environ and add Unicode
// support (neither of which is likely to be of great importance).
#ifdef AVIAN_IOS
namespace {
const char* environ[] = {0};
}
#elif defined __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#elif defined(WINAPI_FAMILY) \
&& !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// WinRT/WP8 does not provide alternative for environment variables
char* environ[] = {0};
#else
extern char** environ;
#endif
extern "C" JNIEXPORT jobjectArray JNICALL
Java_java_lang_System_getEnvironment(JNIEnv* env, jclass)
{
int length;
for (length = 0; environ[length] != 0; ++length)
;
jobjectArray stringArray = env->NewObjectArray(
length, env->FindClass("java/lang/String"), env->NewStringUTF(""));
for (int i = 0; i < length; i++) {
jobject varString = env->NewStringUTF(environ[i]);
env->SetObjectArrayElement(stringArray, i, varString);
}
return stringArray;
}
extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef PLATFORM_WINDOWS
// We used to use _ftime here, but that only gives us 1-second
// resolution on Windows 7. _ftime_s might work better, but MinGW
// doesn't have it as of this writing. So we use this mess instead:
FILETIME time;
GetSystemTimeAsFileTime(&time);
return (((static_cast<jlong>(time.dwHighDateTime) << 32) | time.dwLowDateTime)
/ 10000) - 11644473600000LL;
#else
timeval tv = {0, 0};
gettimeofday(&tv, 0);
return (static_cast<jlong>(tv.tv_sec) * 1000)
+ (static_cast<jlong>(tv.tv_usec) / 1000);
#endif
}
extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name)
{

View File

@ -1,145 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef SGX
#include "jni.h"
#include "avian/machine.h"
#include "sockets.h"
#include "jni-util.h"
using namespace avian::classpath::sockets;
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_init(JNIEnv* e, jclass)
{
init(e);
}
extern "C" JNIEXPORT SOCKET JNICALL
Java_java_net_Socket_create(JNIEnv* e, jclass)
{
return create(e);
}
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_connect(JNIEnv* e,
jclass,
jlong sock,
jlong addr,
jshort port)
{
connect(e, static_cast<SOCKET>(sock), addr, port);
}
extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_bind(JNIEnv* e,
jclass,
jlong sock,
jlong addr,
jshort port)
{
bind(e, static_cast<SOCKET>(sock), addr, port);
}
extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_abort(JNIEnv* e, jclass, jlong sock)
{
abort(e, static_cast<SOCKET>(sock));
}
extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_close(JNIEnv* e, jclass, jlong sock)
{
close(e, static_cast<SOCKET>(sock));
}
extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_closeOutput(JNIEnv* e, jclass, jlong sock)
{
close_output(e, static_cast<SOCKET>(sock));
}
extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_closeInput(JNIEnv* e, jclass, jlong sock)
{
close_input(e, static_cast<SOCKET>(sock));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments)
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
t, reinterpret_cast<vm::object>(arguments[2]));
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments)
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
t, reinterpret_cast<vm::object>(arguments[2]));
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e,
jclass,
jstring name)
{
if(!name) {
throwNew(e, "java/lang/NullPointerException", 0);
return 0;
}
const char* chars = e->GetStringUTFChars(name, 0);
if (chars) {
#ifdef PLATFORM_WINDOWS
hostent* host = gethostbyname(chars);
e->ReleaseStringUTFChars(name, chars);
if (host) {
return ntohl(reinterpret_cast<in_addr*>(host->h_addr_list[0])->s_addr);
} else {
throwNew(e, "java/net/UnknownHostException", 0);
return 0;
}
#else
addrinfo hints;
memset(&hints, 0, sizeof(addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
addrinfo* result;
int r = getaddrinfo(chars, 0, &hints, &result);
e->ReleaseStringUTFChars(name, chars);
if (r != 0) {
throwNew(e, "java/net/UnknownHostException", 0);
return 0;
} else {
int address = ntohl(
reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr);
freeaddrinfo(result);
return address;
}
#endif
} else {
throwNew(e, "java/lang/OutOfMemoryError", 0);
return 0;
}
}
#endif // !SGX

View File

@ -85,18 +85,6 @@ inline jbyteArray errorString(JNIEnv* e, int n)
#endif
}
inline jbyteArray socketErrorString(JNIEnv* e, int n)
{
#ifdef PLATFORM_WINDOWS
const unsigned size = 64;
char buffer[size];
snprintf(buffer, size, "wsa code: %d", n);
return charsToArray(e, buffer);
#else
return errorString(e, n);
#endif
}
inline jbyteArray errorString(JNIEnv* e)
{
#ifdef PLATFORM_WINDOWS
@ -132,37 +120,6 @@ void throwIOException(JNIEnv* e)
throwIOException(e, errorString(e));
}
void throwSocketException(JNIEnv* e, const char* s)
{
throwNew(e, "java/net/SocketException", s);
}
void throwSocketException(JNIEnv* e, jbyteArray a)
{
size_t length = e->GetArrayLength(a);
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) {
e->GetByteArrayRegion(a, 0, length, reinterpret_cast<jbyte*>(buf));
throwSocketException(e, reinterpret_cast<const char*>(buf));
free(buf);
} else {
return;
}
}
void throwSocketException(JNIEnv* e)
{
throwSocketException(e, errorString(e));
}
void init(sockaddr_in* address, jint host, jint port)
{
memset(address, 0, sizeof(sockaddr_in));
address->sin_family = AF_INET;
address->sin_port = htons(port);
address->sin_addr.s_addr = htonl(host);
}
inline bool einProgress(int error)
{
#ifdef PLATFORM_WINDOWS
@ -172,26 +129,6 @@ inline bool einProgress(int error)
#endif
}
inline bool einProgress()
{
#ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EINPROGRESS;
#endif
}
inline bool eagain()
{
#ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EAGAIN;
#endif
}
bool setBlocking(JNIEnv* e, int d, bool blocking)
{
#ifdef PLATFORM_WINDOWS
@ -214,609 +151,32 @@ bool setBlocking(JNIEnv* e, int d, bool blocking)
return true;
}
bool setTcpNoDelay(JNIEnv* e, int d, bool on)
{
int flag = on;
int r = setsockopt(
d, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&flag), sizeof(int));
if (r < 0) {
throwSocketException(e);
return false;
}
return true;
}
void doBind(JNIEnv* e, int s, sockaddr_in* address)
{
{
int opt = 1;
int r = ::setsockopt(s,
SOL_SOCKET,
SO_REUSEADDR,
reinterpret_cast<char*>(&opt),
sizeof(int));
if (r != 0) {
throwIOException(e);
return;
}
}
#ifdef SO_NOSIGPIPE
{
int opt = 1;
int r = ::setsockopt(s,
SOL_SOCKET,
SO_NOSIGPIPE,
reinterpret_cast<char*>(&opt),
sizeof(int));
if (r != 0) {
throwIOException(e);
return;
}
}
#endif
{
int r
= ::bind(s, reinterpret_cast<sockaddr*>(address), sizeof(sockaddr_in));
if (r != 0) {
throwIOException(e);
return;
}
}
}
void doListen(JNIEnv* e, int s)
{
int r = ::listen(s, 100);
if (r != 0) {
throwIOException(e);
}
}
void doFinishConnect(JNIEnv* e, int socket)
{
int error;
socklen_t size = sizeof(int);
int r = getsockopt(
socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) {
throwIOException(e);
} else if (error and not einProgress(error)) {
throwIOException(e, socketErrorString(e, error));
}
}
bool doConnect(JNIEnv* e, int s, sockaddr_in* address)
{
int r
= ::connect(s, reinterpret_cast<sockaddr*>(address), sizeof(sockaddr_in));
if (r == 0) {
return true;
} else if (not einProgress()) {
throwIOException(e);
return false;
} else {
return false;
}
}
int doAccept(JNIEnv* e, int s)
{
sockaddr address;
socklen_t length = sizeof(address);
int r = ::accept(s, &address, &length);
if (r >= 0) {
return r;
} else if (errno != EINTR) {
throwIOException(e);
}
return -1;
}
int doRead(int fd, void* buffer, size_t count)
inline bool einProgress()
{
#ifdef PLATFORM_WINDOWS
return recv(fd, static_cast<char*>(buffer), count, 0);
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return read(fd, buffer, count);
return errno == EINPROGRESS;
#endif
}
int doRecv(int fd, void* buffer, size_t count, int32_t* host, int32_t* port)
{
sockaddr address;
socklen_t length = sizeof(address);
int r = recvfrom(fd, static_cast<char*>(buffer), count, 0, &address, &length);
if (r > 0) {
sockaddr_in a;
memcpy(&a, &address, length);
*host = ntohl(a.sin_addr.s_addr);
*port = ntohs(a.sin_port);
} else {
*host = 0;
*port = 0;
}
return r;
}
int doWrite(int fd, const void* buffer, size_t count)
inline bool eagain()
{
#ifdef PLATFORM_WINDOWS
return send(fd, static_cast<const char*>(buffer), count, 0);
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return write(fd, buffer, count);
return errno == EAGAIN;
#endif
}
int doSend(int fd, sockaddr_in* address, const void* buffer, size_t count)
{
return sendto(fd,
static_cast<const char*>(buffer),
count,
0,
reinterpret_cast<sockaddr*>(address),
sizeof(sockaddr_in));
}
int makeSocket(JNIEnv* e, int type = SOCK_STREAM, int protocol = IPPROTO_TCP)
{
int s = ::socket(AF_INET, type, protocol);
if (s < 0) {
throwIOException(e);
return s;
}
return s;
}
} // namespace <anonymous>
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_ServerSocketChannel_natDoAccept(JNIEnv* e,
jclass,
jint socket)
{
return ::doAccept(e, socket);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_ServerSocketChannel_natDoListen(JNIEnv* e,
jclass,
jint socket,
jint host,
jint port)
{
sockaddr_in address;
init(&address, host, port);
::doBind(e, socket, &address);
if (e->ExceptionCheck())
return;
::doListen(e, socket);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_bind(JNIEnv* e,
jclass,
jint socket,
jint host,
jint port)
{
sockaddr_in address;
init(&address, host, port);
::doBind(e, socket, &address);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_DatagramChannel_bind(JNIEnv* e,
jclass c,
jint socket,
jint host,
jint port)
{
Java_java_nio_channels_SocketChannel_bind(e, c, socket, host, port);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_configureBlocking(JNIEnv* e,
jclass,
jint socket,
jboolean blocking)
{
setBlocking(e, socket, blocking);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_DatagramChannel_configureBlocking(JNIEnv* e,
jclass c,
jint socket,
jboolean blocking)
{
return Java_java_nio_channels_SocketChannel_configureBlocking(
e, c, socket, blocking);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natSetTcpNoDelay(JNIEnv* e,
jclass,
jint socket,
jboolean on)
{
setTcpNoDelay(e, socket, on);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv* e,
jclass,
jint socket,
jint host,
jint port)
{
sockaddr_in address;
init(&address, host, port);
return ::doConnect(e, socket, &address);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_makeSocket(JNIEnv* e, jclass)
{
return makeSocket(e);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_makeSocket(JNIEnv* e, jclass)
{
return makeSocket(e, SOCK_DGRAM, IPPROTO_UDP);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_nio_channels_DatagramChannel_connect(JNIEnv* e,
jclass,
jint socket,
jint host,
jint port)
{
sockaddr_in address;
init(&address, host, port);
return ::doConnect(e, socket, &address);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv* e,
jclass,
jint socket)
{
doFinishConnect(e, socket);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_natRead(JNIEnv* e,
jclass,
jint socket,
jbyteArray buffer,
jint offset,
jint length,
jboolean blocking)
{
int r;
if (blocking) {
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) {
r = ::doRead(socket, buf, length);
if (r > 0) {
e->SetByteArrayRegion(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
}
free(buf);
} else {
return 0;
}
} else {
jboolean isCopy;
uint8_t* buf
= static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doRead(socket, buf + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
}
if (r < 0) {
if (eagain()) {
return 0;
} else {
throwIOException(e);
}
} else if (r == 0) {
return -1;
}
return r;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
jclass,
jint socket,
jbyteArray buffer,
jint offset,
jint length,
jboolean blocking,
jintArray address)
{
int r;
int32_t host;
int32_t port;
if (blocking) {
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) {
r = ::doRecv(socket, buf, length, &host, &port);
if (r > 0) {
e->SetByteArrayRegion(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
}
free(buf);
} else {
return 0;
}
} else {
jboolean isCopy;
uint8_t* buf
= static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doRecv(socket, buf + offset, length, &host, &port);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
}
if (r < 0) {
if (eagain()) {
return 0;
} else {
throwIOException(e);
}
} else if (r == 0) {
return -1;
} else {
jint jhost = host;
e->SetIntArrayRegion(address, 0, 1, &jhost);
jint jport = port;
e->SetIntArrayRegion(address, 1, 1, &jport);
}
return r;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_natWrite(JNIEnv* e,
jclass,
jint socket,
jbyteArray buffer,
jint offset,
jint length,
jboolean blocking)
{
int r;
if (blocking) {
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) {
e->GetByteArrayRegion(
buffer, offset, length, reinterpret_cast<jbyte*>(buf));
r = ::doWrite(socket, buf, length);
free(buf);
} else {
return 0;
}
} else {
jboolean isCopy;
uint8_t* buf
= static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doWrite(socket, buf + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
}
if (r < 0) {
if (eagain()) {
return 0;
} else {
throwIOException(e);
}
}
return r;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_write(JNIEnv* e,
jclass c,
jint socket,
jbyteArray buffer,
jint offset,
jint length,
jboolean blocking)
{
return Java_java_nio_channels_SocketChannel_natWrite(
e, c, socket, buffer, offset, length, blocking);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_send(JNIEnv* e,
jclass,
jint socket,
jint host,
jint port,
jbyteArray buffer,
jint offset,
jint length,
jboolean blocking)
{
sockaddr_in address;
init(&address, host, port);
int r;
if (blocking) {
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) {
e->GetByteArrayRegion(
buffer, offset, length, reinterpret_cast<jbyte*>(buf));
r = ::doSend(socket, &address, buf, length);
free(buf);
} else {
return 0;
}
} else {
jboolean isCopy;
uint8_t* buf
= static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doSend(socket, &address, buf + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
}
if (r < 0) {
if (eagain()) {
return 0;
} else {
throwIOException(e);
}
}
return r;
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv* e,
jclass,
jint socket)
{
int error;
socklen_t size = sizeof(int);
int r = getsockopt(
socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) {
throwIOException(e);
} else if (error != 0) {
throwIOException(e, socketErrorString(e, error));
}
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv*,
jclass,
jint socket)
{
doClose(socket);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_DatagramChannel_close(JNIEnv*, jclass, jint socket)
{
doClose(socket);
}
namespace {
class Pipe {
public:
#ifdef PLATFORM_WINDOWS
// The Windows socket API only accepts socket file descriptors, not
// pipe descriptors or others. Thus, to implement
// Selector.wakeup(), we make a socket connection via the loopback
// interface and use it as a pipe.
Pipe(JNIEnv* e) : connected_(false), listener_(-1), reader_(-1), writer_(-1)
{
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = 0;
address.sin_addr.s_addr = inet_addr("127.0.0.1"); // INADDR_LOOPBACK;
listener_ = makeSocket(e);
if (e->ExceptionCheck())
return;
setBlocking(e, listener_, false);
::doBind(e, listener_, &address);
if (e->ExceptionCheck())
return;
::doListen(e, listener_);
if (e->ExceptionCheck())
return;
socklen_t length = sizeof(sockaddr_in);
int r = getsockname(
listener_, reinterpret_cast<sockaddr*>(&address), &length);
if (r) {
throwIOException(e);
return;
}
writer_ = makeSocket(e);
if (e->ExceptionCheck())
return;
setBlocking(e, writer_, true);
connected_ = ::doConnect(e, writer_, &address);
}
void dispose()
{
if (listener_ >= 0)
::doClose(listener_);
if (reader_ >= 0)
::doClose(reader_);
if (writer_ >= 0)
::doClose(writer_);
}
bool connected()
{
return connected_;
}
void setConnected(bool v)
{
connected_ = v;
}
int listener()
{
return listener_;
}
void setListener(int v)
{
listener_ = v;
}
int reader()
{
return reader_;
}
void setReader(int v)
{
reader_ = v;
}
int writer()
{
return writer_;
}
private:
bool connected_;
int listener_;
int reader_;
int writer_;
#else
Pipe(JNIEnv* e)
{
if (::pipe(pipe) != 0) {
@ -856,236 +216,10 @@ class Pipe {
private:
int pipe[2];
bool open_;
#endif
};
struct SelectorState {
fd_set read;
fd_set write;
fd_set except;
Pipe control;
SelectorState(JNIEnv* e) : control(e)
{
}
};
} // namespace
extern "C" JNIEXPORT jlong JNICALL
Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass)
{
void* mem = malloc(sizeof(SelectorState));
if (mem) {
SelectorState* s = new (mem) SelectorState(e);
if (e->ExceptionCheck())
return 0;
if (s) {
FD_ZERO(&(s->read));
FD_ZERO(&(s->write));
FD_ZERO(&(s->except));
return reinterpret_cast<jlong>(s);
}
}
throwNew(e, "java/lang/OutOfMemoryError", 0);
return 0;
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natWakeup(JNIEnv* e,
jclass,
jlong state)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (s->control.connected()) {
const char c = 1;
int r = ::doWrite(s->control.writer(), &c, 1);
if (r != 1) {
throwIOException(e);
}
}
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natClose(JNIEnv*, jclass, jlong state)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
s->control.dispose();
free(s);
}
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natSelectClearAll(JNIEnv*,
jclass,
jint socket,
jlong state)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
FD_CLR(static_cast<unsigned>(socket), &(s->read));
FD_CLR(static_cast<unsigned>(socket), &(s->write));
FD_CLR(static_cast<unsigned>(socket), &(s->except));
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(
JNIEnv*,
jclass,
jint socket,
jint interest,
jlong state,
jint max)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (interest & (java_nio_channels_SelectionKey_OP_READ
| java_nio_channels_SelectionKey_OP_ACCEPT)) {
FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket)
max = socket;
} else {
FD_CLR(static_cast<unsigned>(socket), &(s->read));
}
if (interest & (java_nio_channels_SelectionKey_OP_WRITE
| java_nio_channels_SelectionKey_OP_CONNECT)) {
FD_SET(static_cast<unsigned>(socket), &(s->write));
FD_SET(static_cast<unsigned>(socket), &(s->except));
if (max < socket)
max = socket;
} else {
FD_CLR(static_cast<unsigned>(socket), &(s->write));
}
return max;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv* e,
jclass,
jlong state,
jint max,
jlong interval)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (s->control.reader() >= 0) {
int socket = s->control.reader();
FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket)
max = socket;
}
#ifdef PLATFORM_WINDOWS
if (s->control.listener() >= 0) {
int socket = s->control.listener();
FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket)
max = socket;
}
if (not s->control.connected()) {
int socket = s->control.writer();
FD_SET(static_cast<unsigned>(socket), &(s->write));
FD_SET(static_cast<unsigned>(socket), &(s->except));
if (max < socket)
max = socket;
}
#endif
timeval time;
if (interval > 0) {
time.tv_sec = interval / 1000;
time.tv_usec = (interval % 1000) * 1000;
} else if (interval < 0) {
time.tv_sec = 0;
time.tv_usec = 0;
} else {
time.tv_sec = 24 * 60 * 60 * 1000;
time.tv_usec = 0;
}
int r = ::select(max + 1, &(s->read), &(s->write), &(s->except), &time);
if (r < 0) {
if (errno != EINTR) {
throwIOException(e);
return 0;
}
}
#ifdef PLATFORM_WINDOWS
if (FD_ISSET(s->control.writer(), &(s->write))
or FD_ISSET(s->control.writer(), &(s->except))) {
int socket = s->control.writer();
FD_CLR(static_cast<unsigned>(socket), &(s->write));
FD_CLR(static_cast<unsigned>(socket), &(s->except));
int error;
socklen_t size = sizeof(int);
int r = getsockopt(
socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) {
throwIOException(e);
} else if (error != 0) {
throwIOException(e, socketErrorString(e, error));
}
s->control.setConnected(true);
}
if (s->control.listener() >= 0
and FD_ISSET(s->control.listener(), &(s->read))) {
FD_CLR(static_cast<unsigned>(s->control.listener()), &(s->read));
s->control.setReader(::doAccept(e, s->control.listener()));
s->control.setListener(-1);
}
#endif
if (s->control.reader() >= 0 and FD_ISSET(s->control.reader(), &(s->read))) {
FD_CLR(static_cast<unsigned>(s->control.reader()), &(s->read));
char c;
int r = 1;
while (r == 1) {
r = ::doRead(s->control.reader(), &c, 1);
}
if (r < 0 and not eagain()) {
throwIOException(e);
}
}
return r;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv*,
jclass,
jint socket,
jint interest,
jlong state)
{
SelectorState* s = reinterpret_cast<SelectorState*>(state);
jint ready = 0;
if (FD_ISSET(socket, &(s->read))) {
if (interest & java_nio_channels_SelectionKey_OP_READ) {
ready |= java_nio_channels_SelectionKey_OP_READ;
}
if (interest & java_nio_channels_SelectionKey_OP_ACCEPT) {
ready |= java_nio_channels_SelectionKey_OP_ACCEPT;
}
}
if (FD_ISSET(socket, &(s->write)) or FD_ISSET(socket, &(s->except))) {
if (interest & java_nio_channels_SelectionKey_OP_WRITE) {
ready |= java_nio_channels_SelectionKey_OP_WRITE;
}
if (interest & java_nio_channels_SelectionKey_OP_CONNECT) {
ready |= java_nio_channels_SelectionKey_OP_CONNECT;
}
}
return ready;
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_nio_ByteOrder_isNativeBigEndian(JNIEnv*, jclass)
{
@ -1099,4 +233,4 @@ extern "C" JNIEXPORT jboolean JNICALL
return JNI_FALSE;
}
#endif // !SGX
#endif // !SGX

View File

@ -47,43 +47,6 @@ public class File implements Serializable {
this(parent.getPath() + FileSeparator + child);
}
public static File createTempFile(String prefix, String suffix)
throws IOException
{
return createTempFile(prefix, suffix, null);
}
public static File createTempFile(String prefix, String suffix,
File directory)
throws IOException
{
if(directory == null) {
directory = new File(System.getProperty("java.io.tmpdir"));
}
if(suffix == null) {
suffix = ".tmp";
}
File ret;
long state = System.currentTimeMillis();
do {
ret = generateFile(directory, prefix, state, suffix);
state *= 7;
state += 3;
} while(ret == null);
ret.createNewFile();
return ret;
}
private static File generateFile(File directory, String prefix, long state, String suffix) {
File ret = new File(directory, prefix + state + suffix);
if(ret.exists()) {
return null;
} else {
return ret;
}
}
private static String stripSeparators(String p) {
while (p.length() > 1 && p.endsWith(FileSeparator)) {
p = p.substring(0, p.length() - 1);
@ -104,12 +67,6 @@ public class File implements Serializable {
("\\".equals(FileSeparator) ? path.replace('/', '\\') : path);
}
public static native boolean rename(String old, String new_);
public boolean renameTo(File newName) {
return rename(path, newName.path);
}
private static native boolean isDirectory(String path);
public boolean isDirectory() {
@ -144,16 +101,6 @@ public class File implements Serializable {
return canExecute(path);
}
private static native boolean setExecutable(String path, boolean executable, boolean ownerOnly);
public boolean setExecutable(boolean executable) {
return setExecutable(executable, true);
}
public boolean setExecutable(boolean executable, boolean ownerOnly) {
return setExecutable(path, executable, ownerOnly);
}
public String getName() {
int index = path.lastIndexOf(FileSeparator);
if (index >= 0) {
@ -219,46 +166,6 @@ public class File implements Serializable {
return exists(path);
}
private static native void mkdir(String path) throws IOException;
public boolean mkdir() {
try {
mkdir(path);
return true;
} catch (IOException e) {
return false;
}
}
private static native boolean createNewFile(String path) throws IOException;
public boolean createNewFile() throws IOException {
return createNewFile(path);
}
public static native void delete(String path) throws IOException;
public boolean delete() {
try {
delete(path);
return true;
} catch (IOException e) {
return false;
}
}
public boolean mkdirs() {
File parent = getParentFile();
if (parent != null) {
if (!parent.exists()) {
if (!parent.mkdirs()) {
return false;
}
}
}
return mkdir();
}
public File[] listFiles() {
return listFiles(null);
}

View File

@ -1,443 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.io;
import static java.io.ObjectOutputStream.STREAM_MAGIC;
import static java.io.ObjectOutputStream.STREAM_VERSION;
import static java.io.ObjectOutputStream.TC_NULL;
import static java.io.ObjectOutputStream.TC_REFERENCE;
import static java.io.ObjectOutputStream.TC_CLASSDESC;
import static java.io.ObjectOutputStream.TC_OBJECT;
import static java.io.ObjectOutputStream.TC_STRING;
import static java.io.ObjectOutputStream.TC_ARRAY;
import static java.io.ObjectOutputStream.TC_CLASS;
import static java.io.ObjectOutputStream.TC_BLOCKDATA;
import static java.io.ObjectOutputStream.TC_ENDBLOCKDATA;
import static java.io.ObjectOutputStream.TC_RESET;
import static java.io.ObjectOutputStream.TC_BLOCKDATALONG;
import static java.io.ObjectOutputStream.TC_EXCEPTION;
import static java.io.ObjectOutputStream.TC_LONGSTRING;
import static java.io.ObjectOutputStream.TC_PROXYCLASSDESC;
import static java.io.ObjectOutputStream.TC_ENUM;
import static java.io.ObjectOutputStream.SC_WRITE_METHOD;
import static java.io.ObjectOutputStream.SC_BLOCK_DATA;
import static java.io.ObjectOutputStream.SC_SERIALIZABLE;
import static java.io.ObjectOutputStream.SC_EXTERNALIZABLE;
import static java.io.ObjectOutputStream.SC_ENUM;
import static java.io.ObjectOutputStream.getReadOrWriteMethod;
import avian.VMClass;
import java.util.ArrayList;
import java.util.HashMap;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ObjectInputStream extends InputStream implements DataInput {
private final static int HANDLE_OFFSET = 0x7e0000;
private final InputStream in;
private final ArrayList references;
public ObjectInputStream(InputStream in) throws IOException {
this.in = in;
short signature = (short)rawShort();
if (signature != STREAM_MAGIC) {
throw new IOException("Unrecognized signature: 0x"
+ Integer.toHexString(signature));
}
int version = rawShort();
if (version != STREAM_VERSION) {
throw new IOException("Unsupported version: " + version);
}
references = new ArrayList();
}
public int read() throws IOException {
return in.read();
}
private int rawByte() throws IOException {
int c = read();
if (c < 0) {
throw new EOFException();
}
return c;
}
private int rawShort() throws IOException {
return (rawByte() << 8) | rawByte();
}
private int rawInt() throws IOException {
return (rawShort() << 16) | rawShort();
}
private long rawLong() throws IOException {
return ((rawInt() & 0xffffffffl) << 32) | rawInt();
}
private String rawString() throws IOException {
int length = rawShort();
byte[] array = new byte[length];
readFully(array);
return new String(array);
}
public int read(byte[] b, int offset, int length) throws IOException {
return in.read(b, offset, length);
}
public void readFully(byte[] b) throws IOException {
readFully(b, 0, b.length);
}
public void readFully(byte[] b, int offset, int length) throws IOException {
while (length > 0) {
int count = read(b, offset, length);
if (count < 0) {
throw new EOFException("Reached EOF " + length + " bytes too early");
}
offset += count;
length -= count;
}
}
public String readLine() throws IOException {
int c = read();
if (c < 0) {
return null;
} else if (c == '\n') {
return "";
}
StringBuilder builder = new StringBuilder();
for (;;) {
builder.append((char)c);
c = read();
if (c < 0 || c == '\n') {
return builder.toString();
}
}
}
public void close() throws IOException {
in.close();
}
private int remainingBlockData;
private int rawBlockDataByte() throws IOException {
while (remainingBlockData <= 0) {
int b = rawByte();
if (b == TC_BLOCKDATA) {
remainingBlockData = rawByte();
} else {
throw new UnsupportedOperationException("Unknown token: 0x"
+ Integer.toHexString(b));
}
}
--remainingBlockData;
return rawByte();
}
private int rawBlockDataShort() throws IOException {
return (rawBlockDataByte() << 8) | rawBlockDataByte();
}
private int rawBlockDataInt() throws IOException {
return (rawBlockDataShort() << 16) | rawBlockDataShort();
}
private long rawBlockDataLong() throws IOException {
return ((rawBlockDataInt() & 0xffffffffl) << 32) | rawBlockDataInt();
}
public boolean readBoolean() throws IOException {
return rawBlockDataByte() != 0;
}
public byte readByte() throws IOException {
return (byte)rawBlockDataByte();
}
public char readChar() throws IOException {
return (char)rawBlockDataShort();
}
public short readShort() throws IOException {
return (short)rawBlockDataShort();
}
public int readInt() throws IOException {
return rawBlockDataInt();
}
public long readLong() throws IOException {
return rawBlockDataLong();
}
public float readFloat() throws IOException {
return Float.intBitsToFloat(rawBlockDataInt());
}
public double readDouble() throws IOException {
return Double.longBitsToDouble(rawBlockDataLong());
}
public int readUnsignedByte() throws IOException {
return rawBlockDataByte();
}
public int readUnsignedShort() throws IOException {
return rawBlockDataShort();
}
public String readUTF() throws IOException {
int length = rawBlockDataShort();
if (remainingBlockData < length) {
throw new IOException("Short block data: "
+ remainingBlockData + " < " + length);
}
byte[] bytes = new byte[length];
readFully(bytes);
remainingBlockData -= length;
return new String(bytes, "UTF-8");
}
public int skipBytes(int count) throws IOException {
int i = 0;
while (i < count) {
if (read() < 0) {
return i;
}
++i;
}
return count;
}
private static Class charToPrimitiveType(int c) {
if (c == 'B') {
return Byte.TYPE;
} else if (c == 'C') {
return Character.TYPE;
} else if (c == 'D') {
return Double.TYPE;
} else if (c == 'F') {
return Float.TYPE;
} else if (c == 'I') {
return Integer.TYPE;
} else if (c == 'J') {
return Long.TYPE;
} else if (c == 'S') {
return Short.TYPE;
} else if (c == 'Z') {
return Boolean.TYPE;
}
throw new RuntimeException("Unhandled char: " + (char)c);
}
private void expectToken(int token) throws IOException {
int c = rawByte();
if (c != token) {
throw new UnsupportedOperationException("Unexpected token: 0x"
+ Integer.toHexString(c));
}
}
private void field(Field field, Object o)
throws IOException, IllegalArgumentException, IllegalAccessException,
ClassNotFoundException
{
Class type = field.getType();
if (!type.isPrimitive()) {
field.set(o, readObject());
} else {
if (type == Byte.TYPE) {
field.setByte(o, (byte)rawByte());
} else if (type == Character.TYPE) {
field.setChar(o, (char)rawShort());
} else if (type == Double.TYPE) {
field.setDouble(o, Double.longBitsToDouble(rawLong()));
} else if (type == Float.TYPE) {
field.setFloat(o, Float.intBitsToFloat(rawInt()));
} else if (type == Integer.TYPE) {
field.setInt(o, rawInt());
} else if (type == Long.TYPE) {
field.setLong(o, rawLong());
} else if (type == Short.TYPE) {
field.setShort(o, (short)rawShort());
} else if (type == Boolean.TYPE) {
field.setBoolean(o, rawByte() != 0);
} else {
throw new IOException("Unhandled type: " + type);
}
}
}
public Object readObject() throws IOException, ClassNotFoundException {
int c = rawByte();
if (c == TC_NULL) {
return null;
}
if (c == TC_STRING) {
int length = rawShort();
byte[] bytes = new byte[length];
readFully(bytes);
String s = new String(bytes, "UTF-8");
references.add(s);
return s;
}
if (c == TC_REFERENCE) {
int handle = rawInt();
return references.get(handle - HANDLE_OFFSET);
}
if (c != TC_OBJECT) {
throw new IOException("Unexpected token: 0x"
+ Integer.toHexString(c));
}
// class desc
c = rawByte();
ClassDesc classDesc;
if (c == TC_REFERENCE) {
int handle = rawInt() - HANDLE_OFFSET;
classDesc = (ClassDesc)references.get(handle);
} else if (c == TC_CLASSDESC) {
classDesc = classDesc();
} else {
throw new UnsupportedOperationException("Unexpected token: 0x"
+ Integer.toHexString(c));
}
try {
Object o = makeInstance(classDesc.clazz.vmClass);
references.add(o);
do {
Object o1 = classDesc.clazz.cast(o);
boolean customized = (classDesc.flags & SC_WRITE_METHOD) != 0;
Method readMethod = customized ?
getReadOrWriteMethod(o, "readObject") : null;
if (readMethod == null) {
if (customized) {
throw new IOException("Could not find required readObject method "
+ "in " + classDesc.clazz);
}
defaultReadObject(o, classDesc.fields);
} else {
current = o1;
currentFields = classDesc.fields;
readMethod.invoke(o, this);
current = null;
currentFields = null;
expectToken(TC_ENDBLOCKDATA);
}
} while ((classDesc = classDesc.superClassDesc) != null);
return o;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
private static class ClassDesc {
Class clazz;
int flags;
Field[] fields;
ClassDesc superClassDesc;
}
private ClassDesc classDesc() throws ClassNotFoundException, IOException {
ClassDesc result = new ClassDesc();
String className = rawString();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
result.clazz = loader.loadClass(className);
long serialVersionUID = rawLong();
try {
Field field = result.clazz.getField("serialVersionUID");
long expected = field.getLong(null);
if (expected != serialVersionUID) {
throw new IOException("Incompatible serial version UID: 0x"
+ Long.toHexString(serialVersionUID) + " != 0x"
+ Long.toHexString(expected));
}
} catch (Exception ignored) { }
references.add(result);
result.flags = rawByte();
if ((result.flags & ~(SC_SERIALIZABLE | SC_WRITE_METHOD)) != 0) {
throw new UnsupportedOperationException("Cannot handle flags: 0x"
+ Integer.toHexString(result.flags));
}
int fieldCount = rawShort();
result.fields = new Field[fieldCount];
for (int i = 0; i < result.fields.length; i++) {
int typeChar = rawByte();
String fieldName = rawString();
try {
result.fields[i] = result.clazz.getDeclaredField(fieldName);
} catch (Exception e) {
throw new IOException(e);
}
Class type;
if (typeChar == '[' || typeChar == 'L') {
String typeName = (String)readObject();
if (typeName.startsWith("L") && typeName.endsWith(";")) {
typeName = typeName.substring(1, typeName.length() - 1)
.replace('/', '.');
}
type = loader.loadClass(typeName);
} else {
type = charToPrimitiveType(typeChar);
}
if (result.fields[i].getType() != type) {
throw new IOException("Unexpected type of field " + fieldName
+ ": expected " + result.fields[i].getType() + " but got " + type);
}
}
expectToken(TC_ENDBLOCKDATA);
int c = rawByte();
if (c == TC_CLASSDESC) {
result.superClassDesc = classDesc();
} else if (c != TC_NULL) {
throw new UnsupportedOperationException("Unexpected token: 0x"
+ Integer.toHexString(c));
}
return result;
}
private Object current;
private Field[] currentFields;
public void defaultReadObject() throws IOException {
defaultReadObject(current, currentFields);
}
private void defaultReadObject(Object o, Field[] fields) throws IOException {
try {
for (Field field : fields) {
field(field, o);
}
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
private static native Object makeInstance(VMClass c);
}

View File

@ -1,337 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.io;
import java.util.ArrayList;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ObjectOutputStream extends OutputStream implements DataOutput {
final static short STREAM_MAGIC = (short)0xaced;
final static short STREAM_VERSION = 5;
final static byte TC_NULL = (byte)0x70;
final static byte TC_REFERENCE = (byte)0x71;
final static byte TC_CLASSDESC = (byte)0x72;
final static byte TC_OBJECT = (byte)0x73;
final static byte TC_STRING = (byte)0x74;
final static byte TC_ARRAY = (byte)0x75;
final static byte TC_CLASS = (byte)0x76;
final static byte TC_BLOCKDATA = (byte)0x77;
final static byte TC_ENDBLOCKDATA = (byte)0x78;
final static byte TC_RESET = (byte)0x79;
final static byte TC_BLOCKDATALONG = (byte)0x7a;
final static byte TC_EXCEPTION = (byte)0x7b;
final static byte TC_LONGSTRING = (byte)0x7c;
final static byte TC_PROXYCLASSDESC = (byte)0x7d;
final static byte TC_ENUM = (byte)0x7e;
final static byte SC_WRITE_METHOD = 0x01; //if SC_SERIALIZABLE
final static byte SC_BLOCK_DATA = 0x08; //if SC_EXTERNALIZABLE
final static byte SC_SERIALIZABLE = 0x02;
final static byte SC_EXTERNALIZABLE = 0x04;
final static byte SC_ENUM = 0x10;
private final OutputStream out;
public ObjectOutputStream(OutputStream out) throws IOException {
this.out = out;
rawShort(STREAM_MAGIC);
rawShort(STREAM_VERSION);
}
public void write(int c) throws IOException {
out.write(c);
}
public void write(byte[] b, int offset, int length) throws IOException {
out.write(b, offset, length);
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
private void rawByte(int v) throws IOException {
out.write((byte)(v & 0xff));
}
private void rawShort(int v) throws IOException {
rawByte(v >> 8);
rawByte(v);
}
private void rawInt(int v) throws IOException {
rawShort(v >> 16);
rawShort(v);
}
private void rawLong(long v) throws IOException {
rawInt((int)(v >> 32));
rawInt((int)(v & 0xffffffffl));
}
private void blockData(int... bytes) throws IOException {
blockData(bytes, null, null);
}
private void blockData(int[] bytes, byte[] bytes2, char[] chars) throws IOException {
int count = (bytes == null ? 0 : bytes.length)
+ (bytes2 == null ? 0 : bytes2.length)
+ (chars == null ? 0 : chars.length * 2);
if (count < 0x100) {
rawByte(TC_BLOCKDATA);
rawByte(count);
} else {
rawByte(TC_BLOCKDATALONG);
rawInt(count);
}
if (bytes != null) {
for (int b : bytes) {
rawByte(b);
}
}
if (bytes2 != null) {
for (byte b : bytes2) {
rawByte(b & 0xff);
}
}
if (chars != null) {
for (char c : chars) {
rawShort((short)c);
}
}
}
public void writeBoolean(boolean v) throws IOException {
blockData(v ? 1 : 0);
}
public void writeByte(int v) throws IOException {
blockData(v);
}
public void writeShort(int v) throws IOException {
blockData(v >> 8, v);
}
public void writeChar(int v) throws IOException {
blockData(v >> 8, v);
}
public void writeInt(int v) throws IOException {
blockData(v >> 24, v >> 16, v >> 8, v);
}
public void writeLong(long v) throws IOException {
int u = (int)(v >> 32), l = (int)(v & 0xffffffff);
blockData(u >> 24, u >> 16, u >> 8, u, l >> 24, l >> 16, l >> 8, l);
}
public void writeFloat(float v) throws IOException {
writeInt(Float.floatToIntBits(v));
}
public void writeDouble(double v) throws IOException {
writeLong(Double.doubleToLongBits(v));
}
public void writeBytes(String s) throws IOException {
blockData(null, s.getBytes(), null);
}
public void writeChars(String s) throws IOException {
blockData(null, null, s.toCharArray());
}
public void writeUTF(String s) throws IOException {
byte[] bytes = s.getBytes();
int length = bytes.length;
blockData(new int[] { length >> 8, length }, bytes, null);
}
private int classHandle;
private void string(String s) throws IOException {
int length = s.length();
rawShort(length);
for (byte b : s.getBytes()) {
rawByte(b);
}
}
private static char primitiveTypeChar(Class type) {
if (type == Byte.TYPE) {
return 'B';
} else if (type == Character.TYPE) {
return 'C';
} else if (type == Double.TYPE) {
return 'D';
} else if (type == Float.TYPE) {
return 'F';
} else if (type == Integer.TYPE) {
return 'I';
} else if (type == Long.TYPE) {
return 'J';
} else if (type == Short.TYPE) {
return 'S';
} else if (type == Boolean.TYPE) {
return 'Z';
}
throw new RuntimeException("Unhandled primitive type: " + type);
}
private void classDesc(Class clazz, int scFlags) throws IOException {
rawByte(TC_CLASSDESC);
// class name
string(clazz.getName());
// serial version UID
long serialVersionUID = 1l;
try {
Field field = clazz.getField("serialVersionUID");
serialVersionUID = field.getLong(null);
} catch (Exception ignored) {}
rawLong(serialVersionUID);
// handle
rawByte(SC_SERIALIZABLE | scFlags);
Field[] fields = getFields(clazz);
rawShort(fields.length);
for (Field field : fields) {
Class fieldType = field.getType();
if (fieldType.isPrimitive()) {
rawByte(primitiveTypeChar(fieldType));
string(field.getName());
} else {
rawByte(fieldType.isArray() ? '[' : 'L');
string(field.getName());
rawByte(TC_STRING);
string("L" + fieldType.getName().replace('.', '/') + ";");
}
}
rawByte(TC_ENDBLOCKDATA); // TODO: write annotation
rawByte(TC_NULL); // super class desc
}
private void field(Object o, Field field) throws IOException {
try {
field.setAccessible(true);
Class type = field.getType();
if (!type.isPrimitive()) {
writeObject(field.get(o));
} else if (type == Byte.TYPE) {
rawByte(field.getByte(o));
} else if (type == Character.TYPE) {
char c = field.getChar(o);
rawShort((short)c);
} else if (type == Double.TYPE) {
double d = field.getDouble(o);
rawLong(Double.doubleToLongBits(d));
} else if (type == Float.TYPE) {
float f = field.getFloat(o);
rawInt(Float.floatToIntBits(f));
} else if (type == Integer.TYPE) {
int i = field.getInt(o);
rawInt(i);
} else if (type == Long.TYPE) {
long l = field.getLong(o);
rawLong(l);
} else if (type == Short.TYPE) {
short s = field.getShort(o);
rawShort(s);
} else if (type == Boolean.TYPE) {
boolean b = field.getBoolean(o);
rawByte(b ? 1 : 0);
} else {
throw new UnsupportedOperationException("Field '" + field.getName()
+ "' has unsupported type: " + type);
}
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
private static Field[] getFields(Class clazz) {
ArrayList<Field> list = new ArrayList<Field>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (0 == (field.getModifiers() &
(Modifier.STATIC | Modifier.TRANSIENT))) {
list.add(field);
}
}
return list.toArray(new Field[list.size()]);
}
public void writeObject(Object o) throws IOException {
if (o == null) {
rawByte(TC_NULL);
return;
}
if (o instanceof String) {
byte[] bytes = ((String)o).getBytes("UTF-8");
rawByte(TC_STRING);
rawShort(bytes.length);
write(bytes);
return;
}
rawByte(TC_OBJECT);
Method writeObject = getReadOrWriteMethod(o, "writeObject");
if (writeObject == null) {
classDesc(o.getClass(), 0);
defaultWriteObject(o);
} else try {
classDesc(o.getClass(), SC_WRITE_METHOD);
current = o;
writeObject.invoke(o, this);
current = null;
rawByte(TC_ENDBLOCKDATA);
} catch (Exception e) {
throw new IOException(e);
}
}
static Method getReadOrWriteMethod(Object o, String methodName) {
try {
Method method = o.getClass().getDeclaredMethod(methodName,
new Class[] { methodName.startsWith("write") ?
ObjectOutputStream.class : ObjectInputStream.class });
method.setAccessible(true);
int modifiers = method.getModifiers();
if ((modifiers & Modifier.STATIC) == 0 ||
(modifiers & Modifier.PRIVATE) != 0) {
return method;
}
} catch (NoSuchMethodException ignored) { }
return null;
}
private Object current;
public void defaultWriteObject() throws IOException {
defaultWriteObject(current);
}
private void defaultWriteObject(Object o) throws IOException {
for (Field field : getFields(o.getClass())) {
field(o, field);
}
}
}

View File

@ -12,7 +12,6 @@ package java.io;
import java.lang.IllegalArgumentException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class RandomAccessFile implements DataInput, Closeable {
@ -229,54 +228,4 @@ public class RandomAccessFile implements DataInput, Closeable {
}
private static native void close(long peer);
public FileChannel getChannel() {
return new FileChannel() {
public void close() {
if (peer != 0) RandomAccessFile.close(peer);
}
public boolean isOpen() {
return peer != 0;
}
public int read(ByteBuffer dst, long position) throws IOException {
if (!dst.hasArray()) throw new IOException("Cannot handle " + dst.getClass());
// TODO: this needs to be synchronized on the Buffer, no?
byte[] array = dst.array();
return readBytes(peer, position, array, dst.position(), dst.remaining());
}
public int read(ByteBuffer dst) throws IOException {
int count = read(dst, position);
if (count > 0) position += count;
return count;
}
public int write(ByteBuffer src, long position) throws IOException {
if (!src.hasArray()) throw new IOException("Cannot handle " + src.getClass());
byte[] array = src.array();
return writeBytes(peer, position, array, src.position(), src.remaining());
}
public int write(ByteBuffer src) throws IOException {
int count = write(src, position);
if (count > 0) position += count;
return count;
}
public long position() throws IOException {
return getFilePointer();
}
public FileChannel position(long position) throws IOException {
seek(position);
return this;
}
public long size() throws IOException {
return length();
}
};
}
}

View File

@ -16,10 +16,6 @@ public final class Math {
public static final double E = 2.718281828459045;
public static final double PI = 3.141592653589793;
private static class Static {
public static final Random random = new Random();
}
private Math() { }
public static double max(double a, double b) {
@ -86,10 +82,6 @@ public final class Math {
return f > 0 ? +1.0f : f < 0 ? -1.0f : 0;
}
public static double random() {
return Static.random.nextDouble();
}
public static native double floor(double v);
public static native double ceil(double v);

View File

@ -22,10 +22,6 @@ import java.util.Hashtable;
import java.util.Properties;
public abstract class System {
private static class NanoTime {
public static final long BaseInMillis = currentTimeMillis();
}
private static class Static {
public static Properties properties = makeProperties();
}
@ -91,14 +87,8 @@ public abstract class System {
private static native String[] getVMProperties();
public static native long currentTimeMillis();
public static native int identityHashCode(Object o);
public static long nanoTime() {
return (currentTimeMillis() - NanoTime.BaseInMillis) * 1000000;
}
public static String mapLibraryName(String name) {
if (name != null) {
return doMapLibraryName(name);

View File

@ -25,7 +25,6 @@ public class Thread implements Runnable {
private byte priority;
private final Runnable task;
private Map<ThreadLocal, Object> locals;
private Object sleepLock;
private ClassLoader classLoader;
private UncaughtExceptionHandler exceptionHandler;
private String name;
@ -158,30 +157,6 @@ public class Thread implements Runnable {
return interrupted;
}
public static void sleep(long milliseconds) throws InterruptedException {
if (milliseconds <= 0) {
milliseconds = 1;
}
Thread t = currentThread();
if (t.sleepLock == null) {
t.sleepLock = new Object();
}
synchronized (t.sleepLock) {
t.sleepLock.wait(milliseconds);
}
}
public static void sleep(long milliseconds, int nanoseconds)
throws InterruptedException
{
if (nanoseconds > 0) {
++ milliseconds;
}
sleep(milliseconds);
}
public StackTraceElement[] getStackTrace() {
long p = peer;
if (p == 0) {
@ -269,27 +244,6 @@ public class Thread implements Runnable {
}
}
public synchronized void join(long milliseconds) throws InterruptedException
{
long then = System.currentTimeMillis();
long remaining = milliseconds;
while (remaining > 0 && getState() != State.TERMINATED) {
wait(remaining);
remaining = milliseconds - (System.currentTimeMillis() - then);
}
}
public void join(long milliseconds, int nanoseconds)
throws InterruptedException
{
if (nanoseconds > 0) {
++ milliseconds;
}
join(milliseconds);
}
public ThreadGroup getThreadGroup() {
return group;
}

View File

@ -1,21 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
public class BindException extends SocketException {
public BindException(String message) {
super(message);
}
public BindException() {
this(null);
}
}

View File

@ -1,19 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
import java.io.IOException;
public abstract class DatagramSocket {
public abstract SocketAddress getRemoteSocketAddress();
public abstract void bind(SocketAddress address) throws SocketException;
}

View File

@ -13,66 +13,20 @@ package java.net;
import java.io.IOException;
public class InetAddress {
private final String name;
private final int ip;
private InetAddress(String name) throws UnknownHostException {
this.name = name;
this.ip = ipv4AddressForName(name);
}
public String getHostName() {
return name;
return null;
}
public String getHostAddress() {
try {
return new InetAddress(name).toString();
} catch (UnknownHostException e) {
return null; // Strange case
}
}
public static InetAddress getByName(String name) throws UnknownHostException {
try {
Socket.init();
return new InetAddress(name);
} catch (IOException e) {
UnknownHostException uhe = new UnknownHostException(name);
uhe.initCause(e);
throw uhe;
}
return null;
}
public byte[] getAddress() {
byte[] res = new byte[4];
res[0] = (byte) ( ip >>> 24);
res[1] = (byte) ((ip >>> 16) & 0xFF);
res[2] = (byte) ((ip >>> 8 ) & 0xFF);
res[3] = (byte) ((ip ) & 0xFF);
return res;
return null;
}
@Override
public String toString() {
byte[] addr = getAddress();
return (int)((addr[0] + 256) % 256) + "." +
(int)((addr[1] + 256) % 256) + "." +
(int)((addr[2] + 256) % 256) + "." +
(int)((addr[3] + 256) % 256);
}
public int getRawAddress() {
return ip;
}
static native int ipv4AddressForName(String name) throws UnknownHostException;
public boolean equals(Object o) {
return o instanceof InetAddress && ((InetAddress) o).ip == ip;
}
public int hashCode() {
return ip;
return -1;
}
}

View File

@ -1,65 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
public class InetSocketAddress extends SocketAddress {
private final String host;
private final InetAddress address;
private final int port;
public InetSocketAddress(String host, int port) {
InetAddress address;
try {
address = InetAddress.getByName(host);
host = address.getHostName();
} catch (UnknownHostException e) {
address = null;
}
this.host = host;
this.address = address;
this.port = port;
}
public InetSocketAddress(InetAddress address, int port) {
this.host = address.getHostName();
this.address = address;
this.port = port;
}
public InetAddress getAddress() {
return address;
}
public String getHostName() {
return host;
}
public int getPort() {
return port;
}
public boolean equals(Object o) {
if (o instanceof InetSocketAddress) {
InetSocketAddress a = (InetSocketAddress) o;
return a.address.equals(address) && a.port == port;
} else {
return false;
}
}
public int hashCode() {
return port ^ address.hashCode();
}
public String toString() {
return getHostName() + ":" + port;
}
}

View File

@ -1,17 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
import java.io.IOException;
public abstract class ServerSocket {
public abstract void bind(SocketAddress address) throws IOException;
}

View File

@ -1,201 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Socket implements Closeable, AutoCloseable {
private static final int SD_RECEIVE = 0x00;
private static final int SD_SEND = 0x01;
private static final int SD_BOTH = 0x02;
private static final int BUFFER_SIZE = 65535;
/**
* This method is called from all routines that depend on winsock in windows,
* so it has public visibility
* @throws IOException
*/
public static native void init() throws IOException;
/**
* Creates the native socket object
* @return Handle to the native object
* @throws IOException
*/
private static native /* SOCKET */long create() throws IOException;
/**
* Connects the native socket object to an address:port
* @param sock Native socket handler
* @param addr Address to connect to
* @param port Port to connect to
* @throws IOException
*/
private static native void connect(/* SOCKET */long sock, long addr, short port) throws IOException;
private static native void bind(/* SOCKET */long sock, long addr, short port) throws IOException;
private static native void send(/* SOCKET */long sock, byte[] buffer, int start_pos, int count) throws IOException;
private static native int recv(/* SOCKET */long sock, byte[] buffer, int start_pos, int count) throws IOException;
private static native void abort(/* SOCKET */long sock);
private static native void close(/* SOCKET */long sock);
private static native void closeOutput(/* SOCKET */long sock);
private static native void closeInput(/* SOCKET */long sock);
private class SocketInputStream extends InputStream {
private boolean closed = false;
@Override
public void close() throws IOException {
if (!closed) {
closeInput(sock);
closed = true;
}
super.close();
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
@Override
public int read() throws IOException {
byte[] buffer = new byte[1];
int size = recv(sock, buffer, 0, 1);
if (size == 0) {
return -1;
}
return buffer[0];
}
@Override
public int read(byte[] buffer) throws IOException {
if(buffer.length == 0) return 0; //spec says return 0 if buffer length is zero.
int fullSize = buffer.length;
int size;
size = recv(sock, buffer, 0, Math.min(fullSize, Socket.BUFFER_SIZE));
fullSize -= size;
//removed loop, because otherwise interactive protocols will not work.
if(size < 0) throw new IOException("Error while reading stream"); //as the manpage of recv says, a value below zero indicates an error.
if(size == 0) return -1; // if the stream is closed (size == 0), then return -1 to indicate end of stream.
return size;
}
}
private class SocketOutputStream extends OutputStream {
private boolean closed = false;
@Override
public void close() throws IOException {
if (!closed) {
closeOutput(sock);
closed = true;
}
super.close();
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
@Override
public void write(int c) throws IOException {
byte[] res = new byte[1];
res[0] = (byte)c;
send(sock, res, 0, 1);
}
@Override
public void write(byte[] buffer) throws IOException {
int fullSize = buffer.length;
int index = 0;
int size;
do {
size = Math.min(fullSize, Socket.BUFFER_SIZE);
send(sock, buffer, index, size);
fullSize -= size;
index += size;
} while (fullSize != 0 && size != 0);
}
}
private long sock;
private SocketInputStream inputStream;
private SocketOutputStream outputStream;
public Socket() throws IOException {
Socket.init();
sock = create();
inputStream = new SocketInputStream();
outputStream = new SocketOutputStream();
}
public SocketInputStream getInputStream() {
return inputStream;
}
public SocketOutputStream getOutputStream() {
return outputStream;
}
public Socket(InetAddress address, int port) throws IOException {
this();
connect(sock, address.getRawAddress(), (short)port);
}
public Socket(String host, int port) throws UnknownHostException, IOException {
this(InetAddress.getByName(host), port);
}
public void bind(SocketAddress bindpoint) throws IOException {
if (bindpoint instanceof InetSocketAddress) {
InetSocketAddress inetBindpoint = (InetSocketAddress)bindpoint;
bind(sock, inetBindpoint.getAddress().getRawAddress(), (short) inetBindpoint.getPort());
}
}
public void setTcpNoDelay(boolean on) throws SocketException {}
@Override
public void close() throws IOException {
close(sock);
}
public void shutdownInput() throws IOException {
inputStream.close();
}
public void shutdownOutput() throws IOException {
outputStream.close();
}
public SocketAddress getRemoteSocketAddress() {
throw new UnsupportedOperationException();
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
}

View File

@ -1,13 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.net;
public abstract class SocketAddress { }

View File

@ -81,9 +81,7 @@ public final class URL {
private static URLStreamHandler findHandler(String protocol)
throws MalformedURLException
{
if ("http".equals(protocol) || "https".equals(protocol)) {
return new avian.http.Handler();
} else if ("avianvmresource".equals(protocol)) {
if ("avianvmresource".equals(protocol)) {
return new avian.avianvmresource.Handler();
} else if ("file".equals(protocol)) {
return new avian.file.Handler();

View File

@ -1,13 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
public class ClosedSelectorException extends IllegalStateException { }

View File

@ -1,239 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.ProtocolFamily;
import java.net.Socket;
import java.net.SocketException;
import java.net.DatagramSocket;
import java.net.StandardProtocolFamily;
// TODO: This class is both divergent from the Java standard and incomplete.
public class DatagramChannel extends SelectableChannel
implements ReadableByteChannel, WritableByteChannel
{
public static final int InvalidSocket = -1;
private int socket = makeSocket();
private boolean blocking = true;
private boolean connected = false;
public SelectableChannel configureBlocking(boolean v) throws IOException {
blocking = v;
configureBlocking();
return this;
}
private void configureBlocking() throws IOException {
if (socket != InvalidSocket) {
configureBlocking(socket, blocking);
}
}
int socketFD() {
return socket;
}
void handleReadyOps(int ops) {
// ignore
}
public static DatagramChannel open(ProtocolFamily family)
throws IOException
{
if (family.equals(StandardProtocolFamily.INET)) {
Socket.init();
return new DatagramChannel();
} else {
throw new UnsupportedOperationException();
}
}
public static DatagramChannel open()
throws IOException
{
return open(StandardProtocolFamily.INET);
}
public DatagramSocket socket() {
return new Handle();
}
public DatagramChannel bind(SocketAddress address) throws IOException {
InetSocketAddress inetAddress;
try {
inetAddress = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
if (inetAddress == null) {
bind(socket, 0, 0);
} else {
bind(socket, inetAddress.getAddress().getRawAddress(),
inetAddress.getPort());
}
return this;
}
public DatagramChannel connect(SocketAddress address) throws IOException {
InetSocketAddress inetAddress;
try {
inetAddress = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
connected = connect(socket, inetAddress.getAddress().getRawAddress(),
inetAddress.getPort());
return this;
}
public int write(ByteBuffer b) throws IOException {
if (b.remaining() == 0) return 0;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int c = write
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
if (c > 0) {
b.position(b.position() + c);
}
return c;
}
public int read(ByteBuffer b) throws IOException {
int p = b.position();
receive(b);
return b.position() - p;
}
public SocketAddress receive(ByteBuffer b) throws IOException {
if (b.remaining() == 0) return null;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int[] address = new int[2];
int c = receive
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking,
address);
if (c > 0) {
b.position(b.position() + c);
return new InetSocketAddress(ipv4ToString(address[0]), address[1]);
} else {
return null;
}
}
public int send(ByteBuffer b, SocketAddress address) throws IOException {
if (b.remaining() == 0) return 0;
InetSocketAddress inetAddress;
try {
inetAddress = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int c = send
(socket, inetAddress.getAddress().getRawAddress(),
inetAddress.getPort(), array, b.arrayOffset() + b.position(),
b.remaining(), blocking);
if (c > 0) {
b.position(b.position() + c);
}
return c;
}
private static String ipv4ToString(int address) {
StringBuilder sb = new StringBuilder();
sb.append( address >> 24 ).append('.')
.append((address >> 16) & 0xFF).append('.')
.append((address >> 8) & 0xFF).append('.')
.append( address & 0xFF);
return sb.toString();
}
public class Handle extends DatagramSocket {
public SocketAddress getRemoteSocketAddress() {
throw new UnsupportedOperationException();
}
public void bind(SocketAddress address) throws SocketException {
try {
DatagramChannel.this.bind(address);
} catch (SocketException e) {
throw e;
} catch (IOException e) {
SocketException se = new SocketException();
se.initCause(e);
throw se;
}
}
}
public boolean isConnected() { return connected; }
/** TODO: This is probably incomplete. */
public DatagramChannel disconnect() throws IOException {
connect(socket, 0, 0);
connected = false;
return this;
}
public void close() throws IOException {
if (isOpen()) {
super.close();
close(socket);
}
}
private static native int makeSocket();
private static native void configureBlocking(int socket, boolean blocking)
throws IOException;
private static native void bind(int socket, int host, int port)
throws IOException;
private static native boolean connect(int socket, int host, int port)
throws IOException;
private static native int write(int socket, byte[] array, int offset,
int length, boolean blocking)
throws IOException;
private static native int send(int socket, int host, int port,
byte[] array, int offset,
int length, boolean blocking)
throws IOException;
private static native int receive(int socket, byte[] array, int offset,
int length, boolean blocking,
int[] address)
throws IOException;
private static native void close(int socket);
}

View File

@ -1,35 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public abstract class FileChannel implements Channel {
public static enum MapMode {
PRIVATE, READ_ONLY, READ_WRITE
};
public abstract int read(ByteBuffer dst) throws IOException;
public abstract int read(ByteBuffer dst, long position) throws IOException;
public abstract int write(ByteBuffer dst) throws IOException;
public abstract int write(ByteBuffer dst, long position) throws IOException;
public abstract long position() throws IOException;
public abstract FileChannel position(long position) throws IOException;
public abstract long size() throws IOException;
}

View File

@ -1,43 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public abstract class SelectableChannel implements Channel {
private SelectionKey key;
private boolean open = true;
abstract int socketFD();
abstract void handleReadyOps(int ops);
public abstract SelectableChannel configureBlocking(boolean v)
throws IOException;
public SelectionKey register(Selector selector, int interestOps,
Object attachment)
{
key = new SelectionKey(this, selector, interestOps, attachment);
selector.add(key);
return key;
}
public boolean isOpen() {
return open;
}
public void close() throws IOException {
open = false;
key = null;
}
}

View File

@ -1,83 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
public class SelectionKey {
public static final int OP_READ = 1 << 0;
public static final int OP_WRITE = 1 << 2;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_ACCEPT = 1 << 4;
private final SelectableChannel channel;
private final Selector selector;
private int interestOps;
private int readyOps;
private final Object attachment;
public SelectionKey(SelectableChannel channel, Selector selector,
int interestOps, Object attachment)
{
this.channel = channel;
this.selector = selector;
this.interestOps = interestOps;
this.attachment = attachment;
this.readyOps = 0;
}
public int interestOps() {
return interestOps;
}
public SelectionKey interestOps(int v) {
this.interestOps = v;
return this;
}
public int readyOps() {
return readyOps;
}
public void readyOps(int v) {
this.readyOps = v;
}
public boolean isReadable() {
return (readyOps & OP_READ) != 0;
}
public boolean isWritable() {
return (readyOps & OP_WRITE) != 0;
}
public boolean isConnectable() {
return (readyOps & OP_CONNECT) != 0;
}
public boolean isAcceptable() {
return (readyOps & OP_ACCEPT) != 0;
}
public boolean isValid() {
return channel.isOpen() && selector.isOpen();
}
public SelectableChannel channel() {
return channel;
}
public Selector selector() {
return selector;
}
public Object attachment() {
return attachment;
}
}

View File

@ -1,52 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
public abstract class Selector {
protected final Set<SelectionKey> keys = new HashSet();
protected final Set<SelectionKey> selectedKeys = new HashSet();
public static Selector open() throws IOException {
return new SocketSelector();
}
public void add(SelectionKey key) {
keys.add(key);
}
public void remove(SelectionKey key) {
keys.remove(key);
}
public Set<SelectionKey> keys() {
return keys;
}
public Set<SelectionKey> selectedKeys() {
return selectedKeys;
}
public abstract boolean isOpen();
public abstract Selector wakeup();
public abstract int selectNow() throws IOException;
public abstract int select(long interval) throws IOException;
public abstract int select() throws IOException;
public abstract void close();
}

View File

@ -1,93 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerSocketChannel extends SelectableChannel {
private final SocketChannel channel;
private ServerSocketChannel() throws IOException {
channel = new SocketChannel();
}
public static ServerSocketChannel open() throws IOException {
Socket.init();
return new ServerSocketChannel();
}
public int socketFD() {
return channel.socketFD();
}
public void handleReadyOps(int ops) {
channel.handleReadyOps(ops);
}
public SelectableChannel configureBlocking(boolean v) throws IOException {
return channel.configureBlocking(v);
}
public void close() throws IOException {
channel.close();
}
public SocketChannel accept() throws IOException {
SocketChannel c = new SocketChannel();
c.socket = doAccept();
c.connected = true;
return c;
}
public ServerSocket socket() {
return new Handle();
}
private int doAccept() throws IOException {
while (true) {
int s = natDoAccept(channel.socket);
if (s != -1) {
return s;
}
// todo: throw ClosedByInterruptException if this thread was
// interrupted during the accept call
}
}
private void doListen(int socket, int host, int port) throws IOException {
Socket.init();
natDoListen(socket, host, port);
}
public class Handle extends ServerSocket {
public void bind(SocketAddress address)
throws IOException
{
InetSocketAddress a;
try {
a = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new IllegalArgumentException();
}
doListen(channel.socket, a.getAddress().getRawAddress(), a.getPort());
}
}
private static native int natDoAccept(int socket) throws IOException;
private static native void natDoListen(int socket, int host, int port) throws IOException;
}

View File

@ -1,214 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.net.SocketException;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel
implements ReadableByteChannel, GatheringByteChannel
{
public static final int InvalidSocket = -1;
int socket = makeSocket();
boolean connected = false;
boolean readyToConnect = false;
boolean blocking = true;
public static SocketChannel open() throws IOException {
Socket.init();
return new SocketChannel();
}
public SelectableChannel configureBlocking(boolean v) throws IOException {
blocking = v;
if (socket != InvalidSocket) {
configureBlocking(socket, v);
}
return this;
}
public boolean isBlocking() {
return blocking;
}
public boolean isConnected() {
return connected;
}
public Socket socket() {
try {
return new Handle();
} catch (IOException e) {
return null;
}
}
public boolean connect(SocketAddress address) throws IOException {
InetSocketAddress a;
try {
a = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
doConnect(socket, a.getAddress().getRawAddress(), a.getPort());
configureBlocking(blocking);
return connected;
}
public boolean finishConnect() throws IOException {
if (! connected) {
while (! readyToConnect) {
Selector selector = Selector.open();
SelectionKey key = register(selector, SelectionKey.OP_CONNECT, null);
if (blocking) {
selector.select();
} else {
selector.selectNow();
break;
}
}
natFinishConnect(socket);
connected = readyToConnect;
}
return connected;
}
public void close() throws IOException {
if (isOpen()) {
super.close();
closeSocket();
}
}
private void doConnect(int socket, int host, int port)
throws IOException
{
connected = natDoConnect(socket, host, port);
}
public int read(ByteBuffer b) throws IOException {
if (! isOpen()) return -1;
if (b.remaining() == 0) return 0;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int r = natRead(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
if (r > 0) {
b.position(b.position() + r);
}
return r;
}
public int write(ByteBuffer b) throws IOException {
if (! connected) {
natThrowWriteError(socket);
}
if (b.remaining() == 0) return 0;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int w = natWrite(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
if (w > 0) {
b.position(b.position() + w);
}
return w;
}
public long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
long total = 0;
for (int i = offset; i < offset + length; ++i) {
total += write(srcs[i]);
if (srcs[i].hasRemaining()) {
return total;
}
}
return total;
}
private void closeSocket() {
natCloseSocket(socket);
}
int socketFD() {
return socket;
}
void handleReadyOps(int ops) {
if ((ops & SelectionKey.OP_CONNECT) != 0) {
readyToConnect = true;
}
}
public class Handle extends Socket {
public Handle() throws IOException {
super();
}
public void setTcpNoDelay(boolean on) throws SocketException {
natSetTcpNoDelay(socket, on);
}
public void bind(SocketAddress address)
throws IOException
{
InetSocketAddress a;
try {
a = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new IllegalArgumentException();
}
if (a == null) {
SocketChannel.bind(socket, 0, 0);
} else {
SocketChannel.bind
(socket, a.getAddress().getRawAddress(), a.getPort());
}
}
}
private static native int makeSocket();
private static native void configureBlocking(int socket, boolean blocking)
throws IOException;
private static native void natSetTcpNoDelay(int socket, boolean on)
throws SocketException;
private static native void bind(int socket, int host, int port)
throws IOException;
private static native boolean natDoConnect(int socket, int host, int port)
throws IOException;
private static native void natFinishConnect(int socket)
throws IOException;
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
throws IOException;
private static native int natWrite(int socket, byte[] buffer, int offset, int length, boolean blocking)
throws IOException;
private static native void natThrowWriteError(int socket) throws IOException;
private static native void natCloseSocket(int socket);
}

View File

@ -1,133 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.util.Iterator;
import java.net.Socket;
class SocketSelector extends Selector {
protected volatile long state;
protected final Object lock = new Object();
protected boolean woken = false;
public SocketSelector() throws IOException {
Socket.init();
state = natInit();
}
public boolean isOpen() {
return state != 0;
}
public Selector wakeup() {
synchronized (lock) {
if (isOpen() && (! woken)) {
woken = true;
natWakeup(state);
}
}
return this;
}
private boolean clearWoken() {
synchronized (lock) {
if (woken) {
woken = false;
return true;
} else {
return false;
}
}
}
public synchronized int selectNow() throws IOException {
return doSelect(-1);
}
public synchronized int select() throws IOException {
return doSelect(0);
}
public synchronized int select(long interval) throws IOException {
if (interval < 0) throw new IllegalArgumentException();
return doSelect(interval);
}
public int doSelect(long interval) throws IOException {
if (! isOpen()) {
throw new ClosedSelectorException();
}
selectedKeys.clear();
if (clearWoken()) interval = -1;
int max=0;
for (Iterator<SelectionKey> it = keys.iterator();
it.hasNext();)
{
SelectionKey key = it.next();
SelectableChannel c = key.channel();
int socket = c.socketFD();
if (c.isOpen()) {
key.readyOps(0);
max = natSelectUpdateInterestSet
(socket, key.interestOps(), state, max);
} else {
natSelectClearAll(socket, state);
it.remove();
}
}
int r = natDoSocketSelect(state, max, interval);
if (r > 0) {
for (SelectionKey key : keys) {
SelectableChannel c = key.channel();
int socket = c.socketFD();
int ready = natUpdateReadySet(socket, key.interestOps(), state);
key.readyOps(ready);
if (ready != 0) {
c.handleReadyOps(ready);
selectedKeys.add(key);
}
}
}
clearWoken();
return selectedKeys.size();
}
public synchronized void close() {
synchronized (lock) {
if (isOpen()) {
natClose(state);
state = 0;
}
}
}
private static native long natInit();
private static native void natWakeup(long state);
private static native void natClose(long state);
private static native void natSelectClearAll(int socket, long state);
private static native int natSelectUpdateInterestSet(int socket,
int interest,
long state,
int max);
private static native int natDoSocketSelect(long state, int max, long interval)
throws IOException;
private static native int natUpdateReadySet(int socket, int interest, long state);
}

View File

@ -11,8 +11,6 @@
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ArrayList<T> extends AbstractList<T> implements java.io.Serializable, RandomAccess {
private static final int MinimumCapacity = 16;
@ -187,23 +185,4 @@ public class ArrayList<T> extends AbstractList<T> implements java.io.Serializabl
public String toString() {
return avian.Data.toString(this);
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeInt(array.length);
for (T o : this) {
out.writeObject(o);
}
}
private void readObject(ObjectInputStream in)
throws ClassNotFoundException, IOException
{
in.defaultReadObject();
int capacity = in.readInt();
grow(capacity);
for (int i = 0; i < size; i++) {
array[i] = in.readObject();
}
}
}

View File

@ -34,7 +34,7 @@ public abstract class Calendar {
protected Calendar() { }
public static Calendar getInstance() {
return new MyCalendar(System.currentTimeMillis());
return new MyCalendar(0);
}
public int get(int field) {

View File

@ -31,10 +31,6 @@ public class Collections {
}
}
public static void shuffle(List list) {
shuffle(list, new Random());
}
public static void sort(List list) {
sort(list, new Comparator() {
public int compare(Object a, Object b) {
@ -200,6 +196,14 @@ public class Collections {
return new ReverseComparator<T>(cmp);
}
public static <T> boolean addAll(Collection<? super T> collection, T... items) {
boolean modified = false;
for (T item : items) {
modified |= collection.add(item);
}
return modified;
}
static class IteratorEnumeration<T> implements Enumeration<T> {
private final Iterator<T> it;

View File

@ -13,10 +13,6 @@ package java.util;
public class Date {
public final long when;
public Date() {
when = System.currentTimeMillis();
}
public Date(long when) {
this.when = when;
}

View File

@ -23,16 +23,6 @@ public class Random {
setSeed(seed);
}
public Random() {
synchronized (Random.class) {
setSeed(nextSeed ^ System.currentTimeMillis());
nextSeed *= 123456789987654321L;
if (nextSeed == 0) {
nextSeed = InitialSeed;
}
}
}
public void setSeed(long seed) {
this.seed = (seed ^ Mask) & ((1L << 48) - 1);
}

View File

@ -11,8 +11,6 @@
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TreeMap<K,V> implements NavigableMap<K,V> {
private final Comparator<K> comparator;
@ -279,26 +277,4 @@ public class TreeMap<K,V> implements NavigableMap<K,V> {
return new avian.Data.ValueIterator(set.iterator());
}
}
public final static long serialVersionUID = 0x0cc1f63e2d256ae6l;
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeInt(size());
for (Entry<K, V> entry : entrySet()) {
out.writeObject(entry.getKey());
out.writeObject(entry.getValue());
}
}
private void readObject(ObjectInputStream in) throws IOException {
in.defaultReadObject();
initializeSet();
int size = in.readInt();
for (int i = 0; i < size; i++) try {
put((K) in.readObject(), (V) in.readObject());
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
}
}

View File

@ -17,19 +17,6 @@ public class UUID {
this.data = data;
}
public static UUID randomUUID() {
byte[] array = new byte[16];
new Random().nextBytes(array);
array[6] &= 0x0f;
array[6] |= 0x40;
array[8] &= 0x3f;
array[8] |= 0x80;
return new UUID(array);
}
public String toString() {
StringBuilder sb = new StringBuilder();
toHex(sb, data, 0, 4); sb.append('-');

View File

@ -1,73 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent;
public class ExecutorCompletionService<T> implements CompletionService<T> {
private final Executor executor;
private final BlockingQueue<Future<T>> completionQueue;
public ExecutorCompletionService(Executor executor) {
this(executor, new LinkedBlockingQueue<Future<T>>());
}
public ExecutorCompletionService(Executor executor, BlockingQueue<Future<T>> completionQueue) {
this.executor = executor;
this.completionQueue = completionQueue;
}
@Override
public Future<T> submit(Callable<T> task) {
ECSFuture f = new ECSFuture(task);
executor.execute(f);
return f;
}
@Override
public Future<T> submit(Runnable task, T result) {
ECSFuture f = new ECSFuture(task, result);
executor.execute(f);
return f;
}
@Override
public Future<T> take() throws InterruptedException {
return completionQueue.take();
}
@Override
public Future<T> poll() {
return completionQueue.poll();
}
@Override
public Future<T> poll(long timeout, TimeUnit unit) throws InterruptedException {
return completionQueue.poll(timeout, unit);
}
private class ECSFuture extends FutureTask<T> implements Future<T> {
private ECSFuture(Runnable r, T result) {
super(r, result);
}
private ECSFuture(Callable<T> callable) {
super(callable);
}
@Override
protected void done() {
completionQueue.add(this);
}
}
}

View File

@ -64,11 +64,7 @@ public class FutureTask<T> implements RunnableFuture<T> {
* and thus thread is in interrupted status, the exception should
* throw immediately on the sleep call.
*/
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
// expected
}
throw new UnsupportedOperationException("Blocking not supported.");
}
Thread.interrupted(); // reset interrupted status if set
@ -127,43 +123,13 @@ public class FutureTask<T> implements RunnableFuture<T> {
@Override
public T get() throws InterruptedException, ExecutionException {
try {
return get(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// not possible
throw new RuntimeException(e);
}
throw new UnsupportedOperationException("System clock unavailable");
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException,
TimeoutException {
long timeoutInMillis = unit.toMillis(timeout);
long startTime = 0;
if (timeoutInMillis < Long.MAX_VALUE) {
startTime = System.currentTimeMillis();
}
long remainingTime;
synchronized (notifyLock) {
remainingTime = timeoutInMillis;
while (! isDone() && remainingTime > 0) {
notifyLock.wait(remainingTime);
if (timeoutInMillis < Long.MAX_VALUE) {
remainingTime = timeoutInMillis - (System.currentTimeMillis() - startTime);
}
}
}
if (remainingTime <= 0) {
throw new TimeoutException();
} else if (currentState.get() == State.Canceled) {
throw new CancellationException();
} else if (failure != null) {
throw new ExecutionException(failure);
} else {
return result;
}
throw new UnsupportedOperationException("System clock unavailable");
}
}

View File

@ -1,302 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util.concurrent;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
public class LinkedBlockingQueue<T> extends AbstractQueue<T>
implements BlockingQueue<T> {
private final Object collectionLock;
private final LinkedList<T> storage;
private final int capacity;
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingQueue(int capacity) {
collectionLock = new Object();
this.capacity = capacity;
storage = new LinkedList<T>();
}
// should be synchronized on collectionLock before calling
private void handleRemove() {
collectionLock.notifyAll();
}
// should be synchronized on collectionLock before calling
private void handleAdd() {
collectionLock.notifyAll();
}
// should be synchronized on collectionLock before calling
private void blockTillNotFull() throws InterruptedException {
blockTillNotFull(Long.MAX_VALUE);
}
// should be synchronized on collectionLock before calling
private void blockTillNotFull(long maxWaitInMillis) throws InterruptedException {
if (capacity > storage.size()) {
return;
}
long startTime = 0;
if (maxWaitInMillis != Long.MAX_VALUE) {
startTime = System.currentTimeMillis();
}
long remainingWait = maxWaitInMillis;
while (remainingWait > 0) {
collectionLock.wait(remainingWait);
if (capacity > storage.size()) {
return;
} else if (maxWaitInMillis != Long.MAX_VALUE) {
remainingWait = maxWaitInMillis - (System.currentTimeMillis() - startTime);
}
}
}
// should be synchronized on collectionLock before calling
private void blockTillNotEmpty() throws InterruptedException {
blockTillNotEmpty(Long.MAX_VALUE);
}
// should be synchronized on collectionLock before calling
private void blockTillNotEmpty(long maxWaitInMillis) throws InterruptedException {
if (! storage.isEmpty()) {
return;
}
long startTime = 0;
if (maxWaitInMillis != Long.MAX_VALUE) {
startTime = System.currentTimeMillis();
}
long remainingWait = maxWaitInMillis;
while (remainingWait > 0) {
collectionLock.wait(remainingWait);
if (! storage.isEmpty()) {
return;
} else if (maxWaitInMillis != Long.MAX_VALUE) {
remainingWait = maxWaitInMillis - (System.currentTimeMillis() - startTime);
}
}
}
@Override
public boolean offer(T element) {
synchronized (collectionLock) {
if (capacity > storage.size()) {
storage.addLast(element);
handleAdd();
return true;
} else {
return false;
}
}
}
@Override
public boolean offer(T e, long timeout, TimeUnit unit) throws InterruptedException {
long timeoutInMillis = unit.toMillis(timeout);
synchronized (collectionLock) {
// block till we can add or have reached timeout
blockTillNotFull(timeoutInMillis);
return offer(e);
}
}
@Override
public void put(T e) throws InterruptedException {
synchronized (collectionLock) {
// block till we have space
blockTillNotFull();
storage.add(e);
handleAdd();
}
}
@Override
public boolean addAll(Collection<? extends T> c) {
synchronized (collectionLock) {
if (storage.size() + c.size() > capacity) {
throw new IllegalStateException("Not enough space");
}
if (c.isEmpty()) {
return false;
} else {
storage.addAll(c);
return true;
}
}
}
@Override
public T peek() {
synchronized (collectionLock) {
if (storage.isEmpty()) {
return null;
} else {
return storage.getFirst();
}
}
}
// should be synchronized on collectionLock before calling
private T removeFirst() {
T result = storage.removeFirst();
handleRemove();
return result;
}
@Override
public T poll() {
synchronized (collectionLock) {
if (storage.isEmpty()) {
return null;
} else {
return removeFirst();
}
}
}
@Override
public T poll(long timeout, TimeUnit unit) throws InterruptedException {
long timeoutInMillis = unit.toMillis(timeout);
synchronized (collectionLock) {
// block till we available or timeout
blockTillNotEmpty(timeoutInMillis);
return poll();
}
}
@Override
public T take() throws InterruptedException {
synchronized (collectionLock) {
// block till we available
blockTillNotEmpty();
return removeFirst();
}
}
@Override
public int drainTo(Collection<? super T> c) {
return drainTo(c, Integer.MAX_VALUE);
}
@Override
public int drainTo(Collection<? super T> c, int maxElements) {
int remainingElements = maxElements;
synchronized (collectionLock) {
while (remainingElements > 0 && ! storage.isEmpty()) {
c.add(storage.removeFirst());
remainingElements--;
}
if (remainingElements != maxElements) {
handleRemove();
}
return maxElements - remainingElements;
}
}
@Override
public int remainingCapacity() {
synchronized (collectionLock) {
return capacity - storage.size();
}
}
@Override
public int size() {
synchronized (collectionLock) {
return storage.size();
}
}
@Override
public boolean contains(Object element) {
synchronized (collectionLock) {
return storage.contains(element);
}
}
@Override
public boolean containsAll(Collection<?> c) {
synchronized (collectionLock) {
return storage.containsAll(c);
}
}
@Override
public boolean remove(Object element) {
synchronized (collectionLock) {
if (storage.remove(element)) {
handleRemove();
return true;
} else {
return false;
}
}
}
@Override
public boolean removeAll(Collection<?> c) {
synchronized (collectionLock) {
if (storage.removeAll(c)) {
handleRemove();
return true;
} else {
return false;
}
}
}
@Override
public void clear() {
synchronized (collectionLock) {
storage.clear();
}
}
@Override
public Object[] toArray() {
synchronized (collectionLock) {
return storage.toArray();
}
}
@Override
public <S> S[] toArray(S[] array) {
synchronized (collectionLock) {
return storage.toArray(array);
}
}
@Override
public Iterator<T> iterator() {
throw new UnsupportedOperationException("Not implemented yet");
}
}

View File

@ -397,20 +397,4 @@ public enum TimeUnit {
obj.wait(ms, ns);
}
}
public void timedJoin(Thread thread, long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
thread.join(ms, ns);
}
}
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns);
}
}
}

View File

@ -48,7 +48,6 @@ public class ZipEntry {
public ZipEntry(String name) {
this.name = name;
setTime(System.currentTimeMillis());
}
//Method to return name of the file

View File

@ -1,205 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
/*
* This file implements a simple cross-platform JNI sockets API
* It is used from different classes of the default Avian classpath
*/
#ifndef SGX
#include "sockets.h"
namespace avian {
namespace classpath {
namespace sockets {
int last_socket_error()
{
#ifdef PLATFORM_WINDOWS
int error = WSAGetLastError();
#else
int error = errno;
#endif
return error;
}
void init(JNIEnv* ONLY_ON_WINDOWS(e))
{
#ifdef PLATFORM_WINDOWS
static bool wsaInitialized = false;
if (not wsaInitialized) {
WSADATA data;
int r = WSAStartup(MAKEWORD(2, 2), &data);
if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
throwNew(e, "java/io/IOException", "WSAStartup failed");
} else {
wsaInitialized = true;
}
}
#endif
}
SOCKET create(JNIEnv* e)
{
SOCKET sock;
if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
char buf[255];
sprintf(
buf, "Can't create a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception
}
return sock;
}
void connect(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr;
adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS
adr.sin_addr.S_un.S_addr = htonl(addr);
#else
adr.sin_addr.s_addr = htonl(addr);
#endif
adr.sin_port = htons(port);
if (SOCKET_ERROR == ::connect(sock, (sockaddr*)&adr, sizeof(adr))) {
char buf[255];
sprintf(
buf, "Can't connect a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
}
void bind(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr;
adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS
adr.sin_addr.S_un.S_addr = htonl(addr);
#else
adr.sin_addr.s_addr = htonl(addr);
#endif
adr.sin_port = htons(port);
if (SOCKET_ERROR == ::bind(sock, (sockaddr*)&adr, sizeof(adr))) {
char buf[255];
sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
}
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port)
{
sockaddr_in adr;
SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL);
if (INVALID_SOCKET == client_socket) {
char buf[255];
sprintf(buf,
"Can't accept the incoming connection. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return INVALID_SOCKET;
}
if (client_addr != NULL) {
#ifdef PLATFORM_WINDOWS
*client_addr = ntohl(adr.sin_addr.S_un.S_addr);
#else
*client_addr = ntohl(adr.sin_addr.s_addr);
#endif
}
if (client_port != NULL) {
*client_port = ntohs(adr.sin_port);
}
return client_socket;
}
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size)
{
if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) {
char buf[255];
sprintf(buf,
"Can't send data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return;
}
}
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size)
{
int length = ::recv(sock, buff_ptr, buff_size, 0);
if (SOCKET_ERROR == length) {
char buf[255];
sprintf(buf,
"Can't receive data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception
}
return length;
}
void abort(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::closesocket(sock)) {
char buf[255];
sprintf(
buf, "Can't close the socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf);
}
}
void close(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_BOTH)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
}
void close_input(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_RECEIVE)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
}
void close_output(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) {
int errcode = last_socket_error();
if (errcode != ENOTCONN) {
char buf[255];
sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
throwNew(e, "java/io/IOException", buf);
}
}
}
}
}
}
#endif

View File

@ -1,74 +0,0 @@
/* Copyright (c) 2008-2015, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
/*
* This file represents a simple cross-platform JNI sockets API
* It is used from different classes of the default Avian classpath
*/
#ifndef SOCKETS_H_
#define SOCKETS_H_
#include "jni.h"
#include "jni-util.h"
#include "avian/common.h"
#ifdef PLATFORM_WINDOWS
#include <winsock2.h>
#define ONLY_ON_WINDOWS(x) x
#ifndef ENOTCONN
#define ENOTCONN WSAENOTCONN
#endif
#else
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define ONLY_ON_WINDOWS(x)
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(x) close(x)
#define SD_RECEIVE SHUT_RD
#define SD_SEND SHUT_WR
#define SD_BOTH SHUT_RDWR
#endif
namespace avian {
namespace classpath {
namespace sockets {
// Library initialization
void init(JNIEnv* ONLY_ON_WINDOWS(e));
// Socket initialization
SOCKET create(JNIEnv* e);
void connect(JNIEnv* e, SOCKET sock, long addr, short port);
void bind(JNIEnv* e, SOCKET sock, long addr, short port);
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port);
// I/O
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size);
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size);
// Socket closing
void abort(JNIEnv* e, SOCKET sock);
void close(JNIEnv* e, SOCKET sock);
void close_input(JNIEnv* e, SOCKET sock);
void close_output(JNIEnv* e, SOCKET sock);
}
}
}
#endif /* SOCKETS_H_ */

14
sgx-jvm/avian/corda.pro Normal file
View File

@ -0,0 +1,14 @@
# proguard include file (http://proguard.sourceforge.net)
# We need these for Corda deserialisation:
-keep class sun.security.ec.ECPublicKeyImpl
-keep class sun.security.ec.ECPrivateKeyImpl
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
-keep class java.lang.invoke.SerializedLambda {
private java.lang.Object readResolve();
}
-keep class com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl

View File

@ -184,6 +184,10 @@ ifneq ($(openjdk),)
x := $(error "android and openjdk are incompatible")
endif
ifeq ($(openjdk-image),)
openjdk-image = $(openjdk)/jre
endif
ifneq ($(openjdk-src),)
include openjdk-src.mk
options := $(options)-openjdk-src
@ -2382,8 +2386,6 @@ $(openjdk-jar-dep):
@mkdir -p $(classpath-build)
(cd $(classpath-build) && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/rt.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/jsse.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/jce.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/charsets.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/resources.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk-image)/lib/ext/sunec.jar")")

View File

@ -94,7 +94,6 @@ openjdk-headers-classes = \
sun.misc.VMSupport \
sun.misc.Version \
sun.misc.URLClassPath \
sun.net.spi.DefaultProxySelector \
sun.nio.ch.IOStatus \
sun.reflect.ConstantPool \
sun.reflect.NativeConstructorAccessorImpl \
@ -214,7 +213,6 @@ else
"-I$(openjdk-src)/solaris/native/java/lang" \
"-I$(openjdk-src)/solaris/native/java/net" \
"-I$(openjdk-src)/solaris/native/java/util" \
"-I$(openjdk-src)/solaris/native/sun/management" \
"-I$(openjdk-src)/solaris/native/sun/nio/ch" \
"-I$(openjdk-src)/solaris/javavm/include" \
"-I$(openjdk-src)/solaris/hpi/include" \

View File

@ -1341,6 +1341,9 @@ class Thread {
return flags;
}
bool isBlacklisting();
void startBlacklisting();
JNIEnvVTable* vtable;
Machine* m;
Thread* parent;

View File

@ -183,6 +183,12 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
t->m->classpath->makeString(t, array, offset, length));
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_avian_SystemClassLoader_startBlacklisting0(Thread* t, object, uintptr_t*)
{
t->startBlacklisting();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_appLoader(Thread* t, object, uintptr_t*)
{

View File

@ -66,6 +66,7 @@ class MyClasspath : public Classpath {
0,
0,
group,
0,
0);
}

View File

@ -3355,7 +3355,7 @@ uint64_t jvmInitProperties(Thread* t, uintptr_t* arguments)
local::setProperty(
t, method, *properties, "java.vm.vendor", "Avian Contributors");
local::setProperty(t, method, *properties, "java.vm.name", "Avian");
local::setProperty(t, method, *properties, "java.vm.name", "Avian (Corda)");
#ifdef AVIAN_VERSION
local::setProperty(t, method, *properties, "java.vm.version", AVIAN_VERSION);
#endif

View File

@ -3964,6 +3964,18 @@ void Thread::dispose()
m->processor->dispose(this);
}
bool Thread::isBlacklisting()
{
return (javaThread != NULL) && javaThread->blacklisting();
}
void Thread::startBlacklisting()
{
if (javaThread != NULL) {
javaThread->setBlacklisting(this, 1);
}
}
void shutDown(Thread* t)
{
ACQUIRE(t, t->m->shutdownLock);
@ -4884,6 +4896,40 @@ GcClass* resolveSystemClass(Thread* t,
ACQUIRE(t, t->m->classLock);
/*
* We require that SystemClassLoader.isForbidden() has already
* been executed once before isBlacklisting is set to true.
* Otherwise this code-block recurses until the stack explodes.
*/
if (t->isBlacklisting()
&& ::strcmp("avian/SystemClassLoader", reinterpret_cast<const char*>(spec->body().begin()))) {
GcMethod* forbid = resolveMethod(t,
roots(t)->bootLoader(),
"avian/SystemClassLoader",
"isForbidden",
"(Ljava/lang/String;)Z");
GcString *name = t->m->classpath->makeString(t, spec, 0, spec->length());
GcInt *result = cast<GcInt>(t, t->m->processor->invoke(t, forbid, NULL, name));
if (UNLIKELY(t->exception)) {
if (throw_) {
GcThrowable* e = t->exception;
t->exception = 0;
vm::throw_(t, e);
} else {
t->exception = 0;
return 0;
}
}
if (result->value() == JNI_TRUE) {
if (throw_) {
throwNew(t, throwType, "%s", spec->body().begin());
} else {
return 0;
}
}
}
GcClass* class_ = findLoadedClass(t, loader, spec);
if (class_ == 0) {
PROTECT(t, class_);

View File

@ -188,6 +188,7 @@
(require object interruptLock)
(require uint8_t interrupted)
(require uint8_t unparked)
(require uint8_t blacklisting)
(alias peer uint64_t eetop)
(alias peer uint64_t nativePeer)
(require uint64_t peer))

View File

@ -51,16 +51,6 @@ public class BufferedInputStreamTest
}
//on all following calls block. The spec says, that a least one byte is returned, if the
//stream is not at EOF.
while(available() == 0)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
}
return 0;
}

View File

@ -1,4 +1,4 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.nio.BufferOverflowException;
@ -9,7 +9,7 @@ public class Buffers {
System.loadLibrary("test");
}
private static void testArrays(Factory factory1, Factory factory2) throws IOException {
private static void testArrays(Factory factory1, Factory factory2) throws UnsupportedEncodingException {
final int size = 64;
ByteBuffer b1 = factory1.allocate(size);
ByteBuffer b2 = factory2.allocate(size);
@ -118,16 +118,6 @@ public class Buffers {
}
};
Factory direct = new Factory() {
public ByteBuffer allocate(int capacity) {
return ByteBuffer.allocateDirect(capacity);
}
public void dispose(ByteBuffer b) {
// ignore
}
};
Factory native_ = new Factory() {
public ByteBuffer allocate(int capacity) {
return allocateNative(capacity);
@ -140,22 +130,11 @@ public class Buffers {
testPrimativeGetAndSet(array, array);
testArrays(array, array);
testPrimativeGetAndSet(array, direct);
testArrays(array, direct);
testPrimativeGetAndSet(array, native_);
testArrays(array, native_);
testPrimativeGetAndSet(direct, array);
testArrays(direct, array);
testPrimativeGetAndSet(direct, direct);
testArrays(direct, direct);
testPrimativeGetAndSet(direct, native_);
testArrays(direct, native_);
testPrimativeGetAndSet(native_, array);
testArrays(native_, array);
testPrimativeGetAndSet(native_, direct);
testArrays(native_, direct);
testPrimativeGetAndSet(native_, native_);
testArrays(native_, native_);

View File

@ -1,54 +0,0 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.TimeUnit;
public class CompletionServiceTest {
public static void main(String args[]) throws InterruptedException, ExecutionException {
Executor dumbExecutor = new Executor() {
@Override
public void execute(Runnable task) {
new Thread(task).start();
}
};
pollNoResultTest(dumbExecutor);
pollTimeoutNoResultTest(dumbExecutor);
takeTest(dumbExecutor);
}
private static void verify(boolean val) {
if (! val) {
throw new RuntimeException();
}
}
private static void pollNoResultTest(Executor executor) {
ExecutorCompletionService<Object> ecs = new ExecutorCompletionService<Object>(executor);
verify(ecs.poll() == null);
}
private static void pollTimeoutNoResultTest(Executor executor) throws InterruptedException {
long delayTime = 0;
ExecutorCompletionService<Object> ecs = new ExecutorCompletionService<Object>(executor);
long startTime = System.currentTimeMillis();
verify(ecs.poll(delayTime, TimeUnit.MILLISECONDS) == null);
verify(System.currentTimeMillis() - startTime >= delayTime);
}
private static void takeTest(Executor executor) throws InterruptedException, ExecutionException {
ExecutorCompletionService<Object> ecs = new ExecutorCompletionService<Object>(executor);
final Object result = new Object();
ecs.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
return result;
}
});
verify(ecs.take().get() == result);
}
}

View File

@ -11,10 +11,6 @@ public class FutureTaskTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
isDoneTest(false);
isDoneTest(true);
getCallableResultTest();
getRunnableResultTest();
getTimeoutFail();
getExecutionExceptionTest();
}
private static void isDoneTest(final boolean throwException) {
@ -34,72 +30,4 @@ public class FutureTaskTest {
throw new RuntimeException("Future should be done");
}
}
private static void getCallableResultTest() throws InterruptedException, ExecutionException {
final Object result = new Object();
FutureTask<Object> future = new FutureTask<Object>(new Callable<Object>() {
@Override
public Object call() throws Exception {
return result;
}
});
future.run();
if (future.get() != result) {
throw new RuntimeException("Bad result returned: " + future.get());
}
}
private static void getRunnableResultTest() throws InterruptedException, ExecutionException {
final Object result = new Object();
FutureTask<Object> future = new FutureTask<Object>(new Runnable() {
@Override
public void run() {
// nothing here
}
}, result);
future.run();
if (future.get() != result) {
throw new RuntimeException("Bad result returned: " + future.get());
}
}
private static void getTimeoutFail() throws InterruptedException,
ExecutionException {
RunnableFuture<?> future = new FutureTask<Object>(new Runnable() {
@Override
public void run() {
// wont run
}
}, null);
long startTime = System.currentTimeMillis();
try {
future.get(DELAY_TIME, TimeUnit.MILLISECONDS);
throw new RuntimeException("Exception should have been thrown");
} catch (TimeoutException e) {
long catchTime = System.currentTimeMillis();
if (catchTime - startTime < DELAY_TIME) {
throw new RuntimeException("get with timeout did not block long enough");
}
}
}
private static void getExecutionExceptionTest() throws InterruptedException, ExecutionException {
FutureTask<Object> future = new FutureTask<Object>(new Runnable() {
@Override
public void run() {
throw new RuntimeException();
}
}, null);
future.run();
try {
future.get();
throw new RuntimeException("Exception should have thrown");
} catch (ExecutionException e) {
// expected
}
}
}

View File

@ -1,208 +0,0 @@
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class LinkedBlockingQueueTest {
private static final int DELAY_TILL_ACTION = 10;
public static void main(String[] args) throws InterruptedException {
remainingCapacityTest();
QueueHelper.sizeTest(new LinkedBlockingQueue<Object>());
QueueHelper.isEmptyTest(new LinkedBlockingQueue<Object>());
QueueHelper.addTest(new LinkedBlockingQueue<Object>());
addCapacityFail();
offerTest();
offerWithTimeoutTest();
offerTimeoutTest();
putTest();
QueueHelper.addAllTest(new LinkedBlockingQueue<Object>());
addAllFail();
QueueHelper.elementTest(new LinkedBlockingQueue<Object>());
QueueHelper.elementFail(new LinkedBlockingQueue<Object>());
pollEmptyTest();
pollTest();
pollTimeoutTest();
takeTest();
QueueHelper.removeEmptyFail(new LinkedBlockingQueue<Object>());
QueueHelper.removeTest(new LinkedBlockingQueue<Object>());
drainToTest();
drainToLimitTest();
QueueHelper.containsTest(new LinkedBlockingQueue<Object>());
QueueHelper.containsAllTest(new LinkedBlockingQueue<Object>());
QueueHelper.removeObjectTest(new LinkedBlockingQueue<Object>());
QueueHelper.removeAllTest(new LinkedBlockingQueue<Object>());
QueueHelper.clearTest(new LinkedBlockingQueue<Object>());
QueueHelper.toArrayTest(new LinkedBlockingQueue<Object>());
}
private static void verify(boolean val) {
if (! val) {
throw new RuntimeException();
}
}
private static void remainingCapacityTest() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(2);
verify(lbq.remainingCapacity() == 2);
lbq.add(new Object());
verify(lbq.remainingCapacity() == 1);
}
private static void addCapacityFail() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(1);
Object testObject = new Object();
lbq.add(testObject);
try {
lbq.add(new Object());
throw new RuntimeException("Exception should have thrown");
} catch (IllegalStateException e) {
// expected
}
verify(lbq.size() == 1);
verify(lbq.peek() == testObject);
}
private static void offerTest() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(1);
Object testObject = new Object();
verify(lbq.offer(testObject));
verify(! lbq.offer(new Object()));
verify(lbq.size() == 1);
verify(lbq.peek() == testObject);
}
private static void offerWithTimeoutTest() throws InterruptedException {
final LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(1);
lbq.add(new Object());
new Thread(new Runnable() {
@Override
public void run() {
try {
// sleep to make sure offer call starts first
Thread.sleep(DELAY_TILL_ACTION);
lbq.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}).start();
// should accept once thread starts
verify(lbq.offer(new Object(), 10, TimeUnit.SECONDS));
}
private static void offerTimeoutTest() throws InterruptedException {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(1);
lbq.add(new Object());
verify(! lbq.offer(new Object(), 10, TimeUnit.MILLISECONDS));
}
private static void putTest() throws InterruptedException {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
Object testObject = new Object();
lbq.put(testObject);
verify(lbq.size() == 1);
verify(lbq.peek() == testObject);
}
private static void addAllFail() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>(1);
LinkedList<Object> toAdd = new LinkedList<Object>();
toAdd.add(new Object());
toAdd.add(new Object());
try {
lbq.addAll(toAdd);
throw new RuntimeException("Exception should have thrown");
} catch (IllegalStateException e) {
// expected
}
}
private static void pollEmptyTest() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
verify(lbq.poll() == null);
}
private static void pollTest() {
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
Object testObject = new Object();
lbq.add(testObject);
verify(lbq.poll() == testObject);
}
private static void pollTimeoutTest() throws InterruptedException {
final LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
final Object testObject = new Object();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(DELAY_TILL_ACTION);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
lbq.add(testObject);
}
}).start();
verify(lbq.poll(DELAY_TILL_ACTION * 10, TimeUnit.MILLISECONDS) == testObject);
}
private static void takeTest() throws InterruptedException {
final LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
final Object testObject = new Object();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(DELAY_TILL_ACTION);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
lbq.add(testObject);
}
}).start();
verify(lbq.take() == testObject);
}
private static void drainToTest() {
int objQty = 2;
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
for (int i = 0; i < objQty; i++) {
lbq.add(new Object());
}
LinkedList<Object> drainToResult = new LinkedList<Object>();
verify(lbq.drainTo(drainToResult) == objQty);
verify(drainToResult.size() == objQty);
}
private static void drainToLimitTest() {
int objQty = 4;
int limit = 2;
LinkedBlockingQueue<Object> lbq = new LinkedBlockingQueue<Object>();
for (int i = 0; i < objQty; i++) {
lbq.add(new Object());
}
LinkedList<Object> drainToResult = new LinkedList<Object>();
verify(lbq.drainTo(drainToResult, limit) == limit);
verify(drainToResult.size() == limit);
verify(lbq.size() == objQty - limit);
}
}

View File

@ -29,7 +29,6 @@ public class MemoryRamp implements Runnable {
* @return time to create and access array in milliseconds
*/
private static long mem() {
long start = System.currentTimeMillis();
final byte[] array = new byte[ARRAY_SIZE];
if (ACCESS_ARRAY) {
for (int i = 0; i < array.length; i++) {
@ -37,7 +36,7 @@ public class MemoryRamp implements Runnable {
byte x = array[i]; //read
}
}
return System.currentTimeMillis() - start;
return 0;
}
/**
@ -46,7 +45,6 @@ public class MemoryRamp implements Runnable {
*/
private static long memMulti(int numOfThreads) {
Thread[] threads = new Thread[numOfThreads];
long start = System.currentTimeMillis();
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new MemoryRamp(), "mem-");
@ -61,6 +59,6 @@ public class MemoryRamp implements Runnable {
catch (InterruptedException iex) {
throw new RuntimeException(iex);
}
return System.currentTimeMillis() - start;
return 0;
}
}

View File

@ -254,8 +254,6 @@ public class Misc {
}
}
System.out.println(new java.util.Date().toString());
System.out.println('x');
System.out.println(true);
System.out.println(42);

View File

@ -1,73 +0,0 @@
package extra;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.io.OutputStream;
import java.io.FileInputStream;
public class SendFile {
private static class SocketOutputStream extends OutputStream {
private final SocketChannel channel;
private final Selector selector;
public SocketOutputStream(String host, int port) throws Exception {
channel = SocketChannel.open();
channel.connect(new InetSocketAddress(host, port));
channel.configureBlocking(false);
selector = Selector.open();
channel.register(selector, SelectionKey.OP_WRITE, null);
}
public void close() throws IOException {
channel.close();
}
public void write(int c) {
throw new RuntimeException("Do not use!");
}
public void write(byte[] buffer, int offset, int length)
throws IOException {
ByteBuffer buf = ByteBuffer.wrap(buffer);
buf.position(offset);
buf.limit(offset+length);
while (buf.hasRemaining()) {
selector.select(10000);
for (SelectionKey key : selector.selectedKeys()) {
if (key.isWritable() && (key.channel() == channel)) {
channel.write(buf);
}
}
}
}
}
public static void sendFile(String file, String host, int port)
throws Exception {
System.out.println("Sending " + file);
OutputStream os = new SocketOutputStream(host, port);
FileInputStream is = new FileInputStream(file);
byte[] buf = new byte[16384];
int count=-1;
while ((count = is.read(buf)) >= 0) {
os.write(buf, 0, count);
}
is.close();
os.close();
}
public static void main(String args[]) {
if (args.length != 2) {
System.out.println("Usage: SendFile file host");
} else {
try {
sendFile(args[0], args[1], 8988);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}

View File

@ -1,92 +0,0 @@
package extra;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class SendServer {
private static char cIndex = 'A';
private static ByteBuffer inBuf = ByteBuffer.allocate(8192);
private static void dumpByteBuffer(char note, ByteBuffer buf) {
System.out.println(note + ": Buffer position: " + buf.position() + " limit: " +
buf.limit() + " capacity: " + buf.capacity() + " remaining: " +
buf.remaining());
}
private static class Connection {
private final char myIndex;
private final java.io.FileOutputStream fos;
public Connection() throws Exception {
myIndex = cIndex++;
fos = new java.io.FileOutputStream("dump." + myIndex);
}
public void handleRead(SocketChannel channel) throws Exception {
int count = -1;
while ((count = channel.read(inBuf)) > 0) {
System.out.println(myIndex + ": read " + count);
}
inBuf.flip();
fos.write(inBuf.array(), inBuf.arrayOffset()+inBuf.position(), inBuf.remaining());
inBuf.position(inBuf.limit());
if (count < 0) {
System.out.println(myIndex + ": Closing channel");
fos.close();
channel.close();
}
// dumpByteBuffer(myIndex, inBuf);
inBuf.compact();
}
}
public void runMainLoop() throws Exception {
boolean keepRunning = true;
int port = 8988;
ServerSocketChannel serverChannel = ServerSocketChannel.open();
try {
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress("0.0.0.0", port));
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT, null);
while (keepRunning) {
System.out.println("Running main loop");
selector.select(10000);
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
System.out.println("Accepting new connection");
SocketChannel c = ((ServerSocketChannel) key.channel()).accept();
if (c != null) {
c.configureBlocking(false);
c.register(selector, SelectionKey.OP_READ, new Connection());
}
} else {
SocketChannel c = (SocketChannel) key.channel();
if (c.isOpen() && key.isReadable()) {
Connection connection = (Connection)key.attachment();
connection.handleRead(c);
}
}
}
selector.selectedKeys().clear();
}
} finally {
serverChannel.close();
}
}
public static void main(String args[]) {
try {
System.out.println("Starting server");
if (args.length > 0) {
new SendServer().runMainLoop();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -1,41 +0,0 @@
package extra;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Sockets {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException,
IOException {
System.out.print("Requesting... " + args[0] + "\n");
Socket sock = new Socket(args[0], 80);
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
String request = "GET /?gws_rd=cr HTTP/1.1\r\n"
+ "Host: " + args[0] + "\r\n" + "Accept: */*\r\n"
+ "User-Agent: Java\r\n" + "Connection: close\r\n" + "\r\n";
bw.write(request);
bw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String read = null;
while ((read = br.readLine()) != null) {
System.out.println(read);
}
bw.close();
} finally {
sock.close();
}
}
}

View File

@ -23,6 +23,7 @@ set(ENCLAVE_SIGNED_OUTPUT_LIB cordaenclave.signed.so)
set(SGX_SIGN_TOOL ${SGX_SDK}/build/linux/sgx_sign)
set(PROGUARD_JAR_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../dependencies/root/usr/share/java/proguard.jar)
set(AVIAN_PATH ${PROJECT_SOURCE_DIR}/../../avian)
set(JDK_IMAGE ${PROJECT_SOURCE_DIR}/../../jdk8u/build/linux-x86_64-normal-server-release/images/j2re-image)
set(ENCLAVE_JAR_PATH ${PROJECT_SOURCE_DIR}/../../../verify-enclave/build/libs/corda-enclavelet.jar)
set(AVIAN_PROCESS "-debug-openjdk-src")
@ -55,8 +56,8 @@ set(PRIVATE_KEY_NAME ${CMAKE_CURRENT_SOURCE_DIR}/selfsigning.pem)
# Now add the compiled class files to our copy of the boot jar (as we need a single uni-jar for everything).
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/encjars/classpath.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/app.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/corda-enclavelet.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/jce.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/jsse.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/sunjce_provider.jar
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create-boot-jar.sh ${AVIAN_PATH}/build/linux-x86_64${AVIAN_PROCESS} ${ENCLAVE_JAR_PATH} ${CMAKE_CURRENT_BINARY_DIR}/encjars ${PROGUARD_JAR_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/proguard.pro ${JAVA_HOME}
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/encjars/classpath.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/app.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/corda-enclavelet.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/jce.jar ${CMAKE_CURRENT_BINARY_DIR}/encjars/jsse.jar
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create-boot-jar.sh ${AVIAN_PATH}/build/linux-x86_64${AVIAN_PROCESS} ${ENCLAVE_JAR_PATH} ${CMAKE_CURRENT_BINARY_DIR}/encjars ${PROGUARD_JAR_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/proguard.pro ${JDK_IMAGE}
DEPENDS ${ENCLAVE_JAR_PATH}
)

View File

@ -6,7 +6,7 @@
# 3) path to the output dir
# 4) path to proguard jar
# 5) path to proguard conf
# 6) path to openjdk install
# 6) path to openjdk image
if [ ! -d "$1" ]; then echo "$1 is not a directory"; exit 1; fi
if [ ! -e "$2" ]; then echo "$2 does not exist"; exit 1; fi
@ -21,7 +21,7 @@ appjar=$( readlink -f $2 )
outputjardir=$( readlink -f $3 )
proguard_jar=$( readlink -f $4 )
proguard_conf=$( readlink -f $5 )
openjdk_libs=$6/jre/lib
openjdk_libs=$6/lib
mkdir -p $outputjardir
if [ ! -e $openjdk_libs/jsse.jar ]; then
@ -29,7 +29,7 @@ if [ ! -e $openjdk_libs/jsse.jar ]; then
exit 1
fi
cmd="java -jar $proguard_jar @$avianpath/../../vm.pro @$avianpath/../../openjdk.pro @$proguard_conf -injars $bootjar -injars $appjar -injars $openjdk_libs/jsse.jar -injars $openjdk_libs/jce.jar -injars $openjdk_libs/ext/sunjce_provider.jar -outjars $outputjardir"
cmd="java -jar $proguard_jar @$avianpath/../../vm.pro @$avianpath/../../openjdk.pro @$avianpath/../../corda.pro @$proguard_conf -injars $bootjar -injars $appjar -injars $openjdk_libs/jsse.jar -injars $openjdk_libs/jce.jar -outjars $outputjardir"
# echo $cmd
$cmd
@ -37,9 +37,12 @@ mkdir -p $outputjardir/temp
cd $outputjardir/temp
jar xf ../jce.jar
jar xf ../jsse.jar
jar xf ../sunjce_provider.jar
jar xf $openjdk_libs/charsets.jar
jar xf $2
rm -f META-INF/*.DSA
rm -f META-INF/*.RSA
rm -f META-INF/*.SF
rm -f META-INF/*.MF
jar cf ../app.jar *
cd ..
rm -r temp

View File

@ -35,8 +35,8 @@ void check_transaction(void *reqbuf, size_t buflen, char *error) {
vmArgs.version = JNI_VERSION_1_2;
vmArgs.ignoreUnrecognized = JNI_TRUE;
char xmxOption[256];
snprintf(xmxOption, 256, "-Xmx%d", g_global_data.heap_size);
char xmxOption[32];
snprintf(xmxOption, sizeof(xmxOption), "-Xmx%d", g_global_data.heap_size);
JavaVMOption options[] = {
// Tell Avian to call the functions above to find the embedded jar data.
// We separate the app into boot and app jars because some code does not
@ -49,9 +49,8 @@ void check_transaction(void *reqbuf, size_t buflen, char *error) {
vmArgs.nOptions = sizeof(options) / sizeof(JavaVMOption);
JavaVM* vm = NULL;
void* env_void = NULL;
JNI_CreateJavaVM(&vm, &env_void, &vmArgs);
JNIEnv* env = static_cast<JNIEnv*>(env_void);
JNIEnv* env = NULL;
JNI_CreateJavaVM(&vm, reinterpret_cast<void**>(&env), &vmArgs);
env->FindClass("com/r3/enclaves/txverify/EnclaveletSerializationScheme");
if (!env->ExceptionCheck()) {
@ -60,7 +59,7 @@ void check_transaction(void *reqbuf, size_t buflen, char *error) {
jmethodID m = env->GetStaticMethodID(c, "verifyInEnclave", "([B)V");
if (!env->ExceptionCheck()) {
jbyteArray reqbits = env->NewByteArray((jsize) buflen);
env->SetByteArrayRegion(reqbits, 0, buflen, (const jbyte *)reqbuf);
env->SetByteArrayRegion(reqbits, 0, buflen, static_cast<const jbyte*>(reqbuf));
jobject result = env->CallStaticObjectMethod(c, m, reqbits);
}
}

View File

@ -2,7 +2,7 @@
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x280000</StackMaxSize>
<HeapMaxSize>0x5500000</HeapMaxSize>
<HeapMaxSize>0x8000000</HeapMaxSize>
<HeapExecutable>1</HeapExecutable>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>

View File

@ -6,7 +6,7 @@
extern "C" {
JNIEXPORT jstring JNICALL Java_com_r3_enclaves_txverify_NativeSgxApi_verify(JNIEnv *env, jobject, jstring enclave_path, jbyteArray transaction) {
JNIEXPORT jstring JNICALL Java_com_r3_enclaves_txverify_NativeSgxApi_verify(JNIEnv *env, jclass, jstring enclave_path, jbyteArray transaction) {
sgx_launch_token_t token = {0};
sgx_enclave_id_t enclave_id = {0};
int updated = 0;
@ -26,4 +26,4 @@ JNIEXPORT jstring JNICALL Java_com_r3_enclaves_txverify_NativeSgxApi_verify(JNIE
}
}
}
}

View File

@ -365,7 +365,7 @@ int CLoader::build_secs(sgx_attributes_t * const secs_attr, sgx_misc_attribute_t
int ret = enclave_creator->create_enclave(&m_secs, &m_enclave_id, &m_start_addr, is_ae(&m_metadata->enclave_css));
if(SGX_SUCCESS == ret)
{
SE_TRACE(SE_TRACE_NOTICE, "enclave start address = %p, size = %x\n", m_start_addr, m_metadata->enclave_size);
SE_TRACE(SE_TRACE_NOTICE, "enclave start address = %p, size = 0x%x\n", m_start_addr, m_metadata->enclave_size);
}
return ret;
}

View File

@ -67,11 +67,16 @@ jar {
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
jvmArgs '-Djava.library.path=../sgx-jvm/jvm-enclave/jni/build'
systemProperties['java.library.path'] = '../sgx-jvm/jvm-enclave/jni/build'
}
test {
// Pending Gradle bug: https://github.com/gradle/gradle/issues/2657
//systemProperties['java.system.class.loader'] = 'com.r3.enclaves.DummySystemClassLoader'
}
task generateNativeSgxHeaders(type: Exec) {
def classpath = sourceSets.main.output.classesDirs.asPath
commandLine "javah", "-o", "build/native/include/jni_sgx_api.h", "-cp", classpath, "com.r3.enclaves.txverify.NativeSgxApi"
commandLine "javah", "-o", "$buildDir/native/include/jni_sgx_api.h", "-cp", classpath, "com.r3.enclaves.txverify.NativeSgxApi"
dependsOn classes
}

View File

@ -7,6 +7,7 @@ import net.corda.core.contracts.Attachment
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.WireTransaction
import java.io.File
@ -14,9 +15,22 @@ import java.io.File
/** This is just used to simplify marshalling across the enclave boundary (EDL is a bit awkward) */
@CordaSerializable
class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransaction>,
val dependencies: Array<SerializedBytes<WireTransaction>>,
val attachments: Array<ByteArray>)
class TransactionVerificationRequest(private val wtxToVerify: SerializedBytes<WireTransaction>,
private val dependencies: Array<SerializedBytes<WireTransaction>>,
val attachments: Array<ByteArray>) {
fun toLedgerTransaction(): LedgerTransaction {
val deps = dependencies.map { it.deserialize() }.associateBy(WireTransaction::id)
val attachments = attachments.map { it.deserialize<Attachment>() }
val attachmentMap = attachments.associateBy(Attachment::id)
val contractAttachmentMap = attachments.mapNotNull { it as? MockContractAttachment }.associateBy(MockContractAttachment::contract)
return wtxToVerify.deserialize().toLedgerTransaction(
resolveIdentity = { null },
resolveAttachment = { attachmentMap[it] },
resolveStateRef = { deps[it.txhash]?.outputs?.get(it.index) },
resolveContractAttachment = { contractAttachmentMap[it.contract]?.id }
)
}
}
/**
* Returns either null to indicate success when the transactions are validated, or a string with the
@ -30,21 +44,26 @@ class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransa
*/
@Throws(Exception::class)
fun verifyInEnclave(reqBytes: ByteArray) {
val req = reqBytes.deserialize<TransactionVerificationRequest>()
val wtxToVerify = req.wtxToVerify.deserialize()
val dependencies = req.dependencies.map { it.deserialize() }.associateBy { it.id }
val attachments = req.attachments.map { it.deserialize<Attachment>() }
val attachmentMap = attachments.associateBy(Attachment::id)
val contractAttachmentMap = attachments.mapNotNull { it as? MockContractAttachment }.associateBy { it.contract }
val ltx = wtxToVerify.toLedgerTransaction(
resolveIdentity = { null },
resolveAttachment = { attachmentMap[it] },
resolveStateRef = { dependencies[it.txhash]?.outputs?.get(it.index) },
resolveContractAttachment = { contractAttachmentMap[it.contract]?.id }
)
val ltx = deserialise(reqBytes)
// Prevent this thread from linking new classes against any
// blacklisted classes, e.g. ones needed by Kryo or by the
// JVM itself. Note that java.lang.Thread is also blacklisted.
startClassBlacklisting()
ltx.verify()
}
private fun startClassBlacklisting() {
val systemClassLoader = ClassLoader.getSystemClassLoader()
systemClassLoader.javaClass.getMethod("startBlacklisting").apply {
invoke(systemClassLoader)
}
}
private fun deserialise(reqBytes: ByteArray): LedgerTransaction {
return reqBytes.deserialize<TransactionVerificationRequest>()
.toLedgerTransaction()
}
// Note: This is only here for debugging purposes
fun main(args: Array<String>) {
Log.TRACE()

View File

@ -5,6 +5,7 @@ import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.core.utilities.ByteSequence
import net.corda.core.utilities.toHexString
import net.corda.nodeapi.internal.serialization.*
import net.corda.nodeapi.internal.serialization.amqp.AbstractAMQPSerializationScheme
import net.corda.nodeapi.internal.serialization.amqp.AmqpHeaderV1_0
@ -29,6 +30,11 @@ private class EnclaveletSerializationScheme {
* incoming request received.
*/
KRYO_P2P_CONTEXT)
/*
* Ensure that we initialise JAXP before blacklisting is enabled.
*/
ByteArray(0).toHexString()
}
}
}

View File

@ -6,5 +6,6 @@ object NativeSgxApi {
System.loadLibrary("untrusted_corda_sgx")
}
@JvmStatic
external fun verify(enclavePath: String, transactionBytes: ByteArray): String?
}
}

View File

@ -0,0 +1,6 @@
package com.r3.enclaves
@Suppress("unused")
class DummySystemClassLoader(parent: ClassLoader) : ClassLoader(parent) {
fun startBlacklisting() {}
}

View File

@ -7,6 +7,7 @@ import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.testing.*
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import java.nio.file.Files
@ -18,6 +19,8 @@ class EnclaveletTest {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
@Ignore("Pending Gradle bug: https://github.com/gradle/gradle/issues/2657")
@Test
fun success() {
ledger {
@ -50,6 +53,7 @@ class EnclaveletTest {
}
}
@Ignore("Pending Gradle bug: https://github.com/gradle/gradle/issues/2657")
@Test
fun fail() {
ledger {