From 4bd1883aab0bb995af9589fb279b61e409a46c65 Mon Sep 17 00:00:00 2001 From: glewis Date: Mon, 2 Feb 2009 07:35:54 +0000 Subject: . Implement the virtual machine interface for BSD. This allows jmap -histo and jmap -dump to work. Submitted by: Brian Gardner Sponsored by: Experts Exchange --- java/jdk16/Makefile | 2 +- .../files/patch-hotspot-vm-attachListener_bsd.cpp | 98 +++++++ .../files/patch-j2se-attach-BSDAttachProvider.java | 44 +++ .../files/patch-j2se-attach-BSDVirtualMachine.c | 286 ++++++++++++++++++++ .../files/patch-j2se-attach-BSDVirtualMachine.java | 297 +++++++++++++++++++++ .../files/patch-j2se-attach-Exportedfiles.gmk | 15 ++ java/jdk16/files/patch-j2se-attach-mapfile-bsd | 28 ++ ...ervices-com.sun.tools.attach.spi.AttachProvider | 9 + 8 files changed, 778 insertions(+), 1 deletion(-) create mode 100644 java/jdk16/files/patch-hotspot-vm-attachListener_bsd.cpp create mode 100644 java/jdk16/files/patch-j2se-attach-BSDAttachProvider.java create mode 100644 java/jdk16/files/patch-j2se-attach-BSDVirtualMachine.c create mode 100644 java/jdk16/files/patch-j2se-attach-BSDVirtualMachine.java create mode 100644 java/jdk16/files/patch-j2se-attach-Exportedfiles.gmk create mode 100644 java/jdk16/files/patch-j2se-attach-mapfile-bsd create mode 100644 java/jdk16/files/patch-j2se-services-com.sun.tools.attach.spi.AttachProvider (limited to 'java') diff --git a/java/jdk16/Makefile b/java/jdk16/Makefile index 83ae0d107263..6409516aa068 100644 --- a/java/jdk16/Makefile +++ b/java/jdk16/Makefile @@ -7,7 +7,7 @@ PORTNAME= jdk PORTVERSION= ${JDK_VERSION}.${JDK_UPDATE_VERSION}p${JDK_PATCHSET_VERSION} -PORTREVISION= 7 +PORTREVISION= 8 CATEGORIES= java devel MASTER_SITES= # http://download.java.net/jdk6/ # http://www.eyesbeyond.com/freebsddom/java/jdk16.html diff --git a/java/jdk16/files/patch-hotspot-vm-attachListener_bsd.cpp b/java/jdk16/files/patch-hotspot-vm-attachListener_bsd.cpp new file mode 100644 index 000000000000..09c545a2510a --- /dev/null +++ b/java/jdk16/files/patch-hotspot-vm-attachListener_bsd.cpp @@ -0,0 +1,98 @@ +$FreeBSD$ + +--- ../../hotspot/src/os/bsd/vm/attachListener_bsd.cpp 28 Mar 2007 04:52:28 -0000 1.1 ++++ ../../hotspot/src/os/bsd/vm/attachListener_bsd.cpp 2 Feb 2009 00:30:06 -0000 +@@ -163,24 +163,11 @@ + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + +- // FIXME: Prior to b39 the tool-side API expected to find the well +- // known file in the working directory. To allow this libjvm.so work with +- // a pre-b39 SDK we create it in the working directory if +- // +StartAttachListener is used is used. All unit tests for this feature +- // currently used this flag. Once b39 SDK has been promoted we can remove +- // this code. +- if (StartAttachListener) { +- sprintf(path, ".java_pid%d", os::current_process_id()); +- strcpy(addr.sun_path, path); +- ::unlink(path); +- res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); +- } +- if (res == -1) { +- sprintf(path, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); +- strcpy(addr.sun_path, path); +- ::unlink(path); +- res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); +- } ++ sprintf(path, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); ++ strcpy(addr.sun_path, path); ++ ::unlink(path); ++ res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); ++ + if (res == -1) { + RESTARTABLE(::close(listener), res); + return -1; +@@ -188,7 +175,7 @@ + set_path(path); + + // put in listen mode and set permission +- if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) { ++ if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1) || (::chown(path,geteuid(),getegid()) == -1)) { + RESTARTABLE(::close(listener), res); + ::unlink(path); + set_path(NULL); +@@ -264,19 +251,19 @@ + } + + // parse request +- ++ + ArgumentIterator args(buf, (max_len)-left); + + // version already checked + char* v = args.next(); +- ++ + char* name = args.next(); + if (name == NULL || strlen(name) > AttachOperation::name_length_max) { + return NULL; + } + + BsdAttachOperation* op = new BsdAttachOperation(name); +- ++ + for (int i=0; i ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sun_tools_attach_BSDVirtualMachine.h" ++ ++#define RESTARTABLE(_cmd, _result) do { \ ++ do { \ ++ _result = _cmd; \ ++ } while((_result == -1) && (errno == EINTR)); \ ++} while(0) ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: socket ++ * Signature: ()I ++ */ ++JNIEXPORT jint JNICALL Java_sun_tools_attach_BSDVirtualMachine_socket ++ (JNIEnv *env, jclass cls) ++{ ++ int fd = socket(PF_UNIX, SOCK_STREAM, 0); ++ if (fd == -1) { ++ JNU_ThrowIOExceptionWithLastError(env, "socket"); ++ } ++ return (jint)fd; ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: connect ++ * Signature: (ILjava/lang/String;)I ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_connect ++ (JNIEnv *env, jclass cls, jint fd, jstring path) ++{ ++ jboolean isCopy; ++ const char* p = GetStringPlatformChars(env, path, &isCopy); ++ if (p != NULL) { ++ struct sockaddr_un addr; ++ int err = 0; ++ ++ addr.sun_family = AF_UNIX; ++ strcpy(addr.sun_path, p); ++ ++ if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { ++ err = errno; ++ } ++ ++ if (isCopy) { ++ JNU_ReleaseStringPlatformChars(env, path, p); ++ } ++ ++ /* ++ * If the connect failed then we throw the appropriate exception ++ * here (can't throw it before releasing the string as can't call ++ * JNI with pending exception) ++ */ ++ if (err != 0) { ++ if (err == ENOENT) { ++ JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL); ++ } else { ++ char* msg = strdup(strerror(err)); ++ JNU_ThrowIOException(env, msg); ++ if (msg != NULL) { ++ free(msg); ++ } ++ } ++ } ++ } ++} ++ ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: sendQuitTo ++ * Signature: (I)V ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_sendQuitTo ++ (JNIEnv *env, jclass cls, jint pid) ++{ ++ if (kill((pid_t)pid, SIGQUIT)) { ++ JNU_ThrowIOExceptionWithLastError(env, "kill"); ++ } ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: checkPermissions ++ * Signature: (Ljava/lang/String;)V ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_checkPermissions ++ (JNIEnv *env, jclass cls, jstring path) ++{ ++ jboolean isCopy; ++ const char* p = GetStringPlatformChars(env, path, &isCopy); ++ if (p != NULL) { ++ struct stat sb; ++ uid_t uid, gid; ++ int res; ++ ++ /* ++ * Check that the path is owned by the effective uid/gid of this ++ * process. Also check that group/other access is not allowed. ++ */ ++ uid = geteuid(); ++ gid = getegid(); ++ ++ res = stat(p, &sb); ++ if (res != 0) { ++ /* save errno */ ++ res = errno; ++ } ++ ++ /* release p here before we throw an I/O exception */ ++ if (isCopy) { ++ JNU_ReleaseStringPlatformChars(env, path, p); ++ } ++ ++ if (res == 0) { ++ if ( (sb.st_uid != uid) || (sb.st_gid != gid) || ++ ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) ) { ++ JNU_ThrowIOException(env, "well-known file is not secure"); ++ } ++ } else { ++ char* msg = strdup(strerror(res)); ++ JNU_ThrowIOException(env, msg); ++ if (msg != NULL) { ++ free(msg); ++ } ++ } ++ } ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: close ++ * Signature: (I)V ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_close ++ (JNIEnv *env, jclass cls, jint fd) ++{ ++ int res; ++ RESTARTABLE(close(fd), res); ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: read ++ * Signature: (I[BI)I ++ */ ++JNIEXPORT jint JNICALL Java_sun_tools_attach_BSDVirtualMachine_read ++ (JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen) ++{ ++ unsigned char buf[128]; ++ size_t len = sizeof(buf); ++ ssize_t n; ++ ++ size_t remaining = (size_t)(baLen - off); ++ if (len > remaining) { ++ len = remaining; ++ } ++ ++ RESTARTABLE(read(fd, buf+off, len), n); ++ if (n == -1) { ++ JNU_ThrowIOExceptionWithLastError(env, "read"); ++ } else { ++ if (n == 0) { ++ n = -1; // EOF ++ } else { ++ (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off)); ++ } ++ } ++ return n; ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: write ++ * Signature: (I[B)V ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_write ++ (JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint bufLen) ++{ ++ size_t remaining = bufLen; ++ do { ++ unsigned char buf[128]; ++ size_t len = sizeof(buf); ++ int n; ++ ++ if (len > remaining) { ++ len = remaining; ++ } ++ (*env)->GetByteArrayRegion(env, ba, off, len, (jbyte *)buf); ++ ++ RESTARTABLE(write(fd, buf, len), n); ++ if (n > 0) { ++ off += n; ++ remaining -= n; ++ } else { ++ JNU_ThrowIOExceptionWithLastError(env, "write"); ++ return; ++ } ++ ++ } while (remaining > 0); ++} ++ ++/* ++ * Class: sun_tools_attach_BSDVirtualMachine ++ * Method: createAttachFile ++ * Signature: (Ljava.lang.String;)V ++ */ ++JNIEXPORT void JNICALL Java_sun_tools_attach_BSDVirtualMachine_createAttachFile(JNIEnv *env, jclass cls, jstring path) ++{ ++ const char* _path; ++ jboolean isCopy; ++ ++ _path = GetStringPlatformChars(env, path, &isCopy); ++ if (_path == NULL) { ++ JNU_ThrowIOException(env, "Must specify a path"); ++ return; ++ } ++ ++ ++ // Consider error handling ++ int fd = -1; ++ RESTARTABLE(open(_path, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR), fd); ++ ++ ++ ++ if (fd == -1) { ++ /* release p here before we throw an I/O exception */ ++ if (isCopy) { ++ JNU_ReleaseStringPlatformChars(env, path, _path); ++ } ++ JNU_ThrowIOExceptionWithLastError(env, "open"); ++ return; ++ } ++ ++ int chown_rc = -1; ++ RESTARTABLE(chown(_path, geteuid(), getegid()), chown_rc); ++ ++ /* release p here before we throw an I/O exception */ ++ if (isCopy) { ++ JNU_ReleaseStringPlatformChars(env, path, _path); ++ } ++ ++ int close_rc = -1; ++ RESTARTABLE(close(fd),close_rc); ++ ++ if (chown_rc == -1) { ++ JNU_ThrowIOExceptionWithLastError(env, "chown"); ++ } ++ if (close_rc == -1) { ++ JNU_ThrowIOExceptionWithLastError(env, "close"); ++ } ++} diff --git a/java/jdk16/files/patch-j2se-attach-BSDVirtualMachine.java b/java/jdk16/files/patch-j2se-attach-BSDVirtualMachine.java new file mode 100644 index 000000000000..0205f5fa8f46 --- /dev/null +++ b/java/jdk16/files/patch-j2se-attach-BSDVirtualMachine.java @@ -0,0 +1,297 @@ +$FreeBSD$ + +--- ../../j2se/src/solaris/classes/sun/tools/attach/BSDVirtualMachine.java 2 Feb 2009 00:28:15 -0000 ++++ ../../j2se/src/solaris/classes/sun/tools/attach/BSDVirtualMachine.java 2 Feb 2009 00:28:15 -0000 +@@ -0,0 +1,292 @@ ++/* ++ * @(#)BSDVirtualMachine.java 1.8 06/03/05 ++ * ++ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. ++ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. ++ */ ++package sun.tools.attach; ++ ++import com.sun.tools.attach.VirtualMachine; ++import com.sun.tools.attach.AgentLoadException; ++import com.sun.tools.attach.AttachNotSupportedException; ++import com.sun.tools.attach.spi.AttachProvider; ++import java.io.InputStream; ++import java.io.IOException; ++import java.io.File; ++import java.util.Properties; ++ ++/* ++ * BSD implementation of HotSpotVirtualMachine ++ */ ++public class BSDVirtualMachine extends HotSpotVirtualMachine { ++ ++ /** ++ * Hard-coded "/tmp" to match the hotspot bsd implementation ++ * hotspot/src/os/bsd/vm/os_bsd.cpp: ++ * const char* os::get_temp_directory() { return "/tmp/"; } ++ */ ++ private static String getTmpDir() { ++ return "/tmp/"; ++ } ++ ++ ++ String path; ++ ++ /** ++ * Attaches to the target VM ++ */ ++ BSDVirtualMachine(AttachProvider provider, String vmid) ++ throws AttachNotSupportedException, IOException ++ { ++ super(provider, vmid); ++ ++ // This provider only understands pids ++ int pid; ++ try { ++ pid = Integer.parseInt(vmid); ++ } catch (NumberFormatException x) { ++ throw new AttachNotSupportedException("Invalid process identifier"); ++ } ++ ++ // Find the socket file. If not found then we attempt to start the ++ // attach mechanism in the target VM by sending it a QUIT signal. ++ // Then we attempt to find the socket file again. ++ path = findSocketFile(pid); ++ if (path == null) { ++ ++ String fn = ".attach_pid" + pid; ++ path = getTmpDir() + fn; ++ File attachFile = new File(path); ++ createAttachFile(path); ++ try { ++ sendQuitTo(pid); ++ ++ // give the target VM time to start the attach mechanism ++ int i = 0; ++ long delay = 200; ++ int retries = (int)(attachTimeout() / delay); ++ do { ++ try { ++ Thread.sleep(delay); ++ } catch (InterruptedException x) { } ++ path = findSocketFile(pid); ++ i++; ++ } while (i <= retries && path == null); ++ if (path == null) { ++ throw new AttachNotSupportedException( ++ "Unable to open socket file: target process not responding " + ++ "or HotSpot VM not loaded"); ++ } ++ } finally { ++ attachFile.delete(); ++ } ++ } ++ ++ // Check that the file owner/permission to avoid attaching to ++ // bogus process ++ checkPermissions(path); ++ ++ // Check that we can connect to the process ++ // - this ensures we throw the permission denied error now rather than ++ // later when we attempt to enqueue a command. ++ int s = socket(); ++ try { ++ connect(s, path); ++ } finally { ++ close(s); ++ } ++ } ++ ++ /** ++ * Detach from the target VM ++ */ ++ public void detach() throws IOException { ++ synchronized (this) { ++ if (this.path != null) { ++ this.path = null; ++ } ++ } ++ } ++ ++ // protocol version ++ private final static String PROTOCOL_VERSION = "1"; ++ ++ // known errors ++ private final static int ATTACH_ERROR_BADVERSION = 101; ++ ++ /** ++ * Execute the given command in the target VM. ++ */ ++ InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException { ++ assert args.length <= 3; // includes null ++ ++ // did we detach? ++ String p; ++ synchronized (this) { ++ if (this.path == null) { ++ throw new IOException("Detached from target VM"); ++ } ++ p = this.path; ++ } ++ ++ // create UNIX socket ++ int s = socket(); ++ ++ // connect to target VM ++ try { ++ connect(s, p); ++ } catch (IOException x) { ++ close(s); ++ throw x; ++ } ++ ++ IOException ioe = null; ++ ++ // connected - write request ++ // ++ try { ++ writeString(s, PROTOCOL_VERSION); ++ writeString(s, cmd); ++ ++ for (int i=0; i<3; i++) { ++ if (i < args.length && args[i] != null) { ++ writeString(s, (String)args[i]); ++ } else { ++ writeString(s, ""); ++ } ++ } ++ } catch (IOException x) { ++ ioe = x; ++ } ++ ++ ++ // Create an input stream to read reply ++ SocketInputStream sis = new SocketInputStream(s); ++ ++ // Read the command completion status ++ int completionStatus; ++ try { ++ completionStatus = readInt(sis); ++ } catch (IOException x) { ++ sis.close(); ++ if (ioe != null) { ++ throw ioe; ++ } else { ++ throw x; ++ } ++ } ++ ++ if (completionStatus != 0) { ++ sis.close(); ++ ++ // In the event of a protocol mismatch then the target VM ++ // returns a known error so that we can throw a reasonable ++ // error. ++ if (completionStatus == ATTACH_ERROR_BADVERSION) { ++ throw new IOException("Protocol mismatch with target VM"); ++ } ++ ++ // Special-case the "load" command so that the right exception is ++ // thrown. ++ if (cmd.equals("load")) { ++ throw new AgentLoadException("Failed to load agent library"); ++ } else { ++ throw new IOException("Command failed in target VM"); ++ } ++ } ++ ++ // Return the input stream so that the command output can be read ++ return sis; ++ } ++ ++ /* ++ * InputStream for the socket connection to get target VM ++ */ ++ private class SocketInputStream extends InputStream { ++ int s; ++ ++ public SocketInputStream(int s) { ++ this.s = s; ++ } ++ ++ public synchronized int read() throws IOException { ++ byte b[] = new byte[1]; ++ int n = this.read(b, 0, 1); ++ if (n == 1) { ++ return b[0] & 0xff; ++ } else { ++ return -1; ++ } ++ } ++ ++ public synchronized int read(byte[] bs, int off, int len) throws IOException { ++ if ((off < 0) || (off > bs.length) || (len < 0) || ++ ((off + len) > bs.length) || ((off + len) < 0)) { ++ throw new IndexOutOfBoundsException(); ++ } else if (len == 0) ++ return 0; ++ ++ return BSDVirtualMachine.read(s, bs, off, len); ++ } ++ ++ public void close() throws IOException { ++ BSDVirtualMachine.close(s); ++ } ++ } ++ ++ ++ // Return the socket file for the given process. ++ // Checks working directory of process for .java_pid. If not ++ // found it looks in /tmp. ++ private String findSocketFile(int pid) { ++ // First check for a .java_pid file in the working directory ++ // of the target process ++ String fn = ".java_pid" + pid; ++ String path = getTmpDir() + fn; ++ File f = new File(path); ++ ++ if (!f.exists()) { ++ return null; // not found ++ } ++ return path; ++ } ++ ++ /* ++ * Write/sends the given to the target VM. String is transmitted in ++ * UTF-8 encoding. ++ */ ++ private void writeString(int fd, String s) throws IOException { ++ if (s.length() > 0) { ++ byte b[]; ++ try { ++ b = s.getBytes("UTF-8"); ++ } catch (java.io.UnsupportedEncodingException x) { ++ throw new InternalError(); ++ } ++ BSDVirtualMachine.write(fd, b, 0, b.length); ++ } ++ byte b[] = new byte[1]; ++ b[0] = 0; ++ write(fd, b, 0, 1); ++ } ++ ++ ++ static native void sendQuitTo(int pid) throws IOException; ++ ++ static native void checkPermissions(String path) throws IOException; ++ ++ static native int socket() throws IOException; ++ ++ static native void connect(int fd, String path) throws IOException; ++ ++ static native void close(int fd) throws IOException; ++ ++ static native int read(int fd, byte buf[], int off, int bufLen) throws IOException; ++ ++ static native void write(int fd, byte buf[], int off, int bufLen) throws IOException; ++ static native void createAttachFile(String path); ++ ++ static { ++ System.loadLibrary("attach"); ++ } ++} diff --git a/java/jdk16/files/patch-j2se-attach-Exportedfiles.gmk b/java/jdk16/files/patch-j2se-attach-Exportedfiles.gmk new file mode 100644 index 000000000000..851873dae0fa --- /dev/null +++ b/java/jdk16/files/patch-j2se-attach-Exportedfiles.gmk @@ -0,0 +1,15 @@ +$FreeBSD$ + +--- ../../j2se/make/com/sun/tools/attach/Exportedfiles.gmk 21 Jul 2006 17:23:23 -0000 1.1.1.2 ++++ ../../j2se/make/com/sun/tools/attach/Exportedfiles.gmk 29 Jan 2009 08:13:19 -0000 +@@ -25,5 +25,10 @@ + sun/tools/attach/LinuxVirtualMachine.java + endif + ++ifeq ($(PLATFORM), bsd) ++FILES_export = \ ++ sun/tools/attach/BSDVirtualMachine.java ++endif ++ + + diff --git a/java/jdk16/files/patch-j2se-attach-mapfile-bsd b/java/jdk16/files/patch-j2se-attach-mapfile-bsd new file mode 100644 index 000000000000..2a079669e31a --- /dev/null +++ b/java/jdk16/files/patch-j2se-attach-mapfile-bsd @@ -0,0 +1,28 @@ +$FreeBSD$ + +--- ../../j2se/make/com/sun/tools/attach/mapfile-bsd 10 May 2007 05:39:49 -0000 1.1 ++++ ../../j2se/make/com/sun/tools/attach/mapfile-bsd 29 Jan 2009 08:13:19 -0000 +@@ -1,5 +1,5 @@ + # +-#ident "@(#)mapfile-linux 1.5 05/11/17" ++#ident "@(#)mapfile-bsd 1.0 09/01/15" + # + # Copyright 2006 Sun Microsystems, Inc. All rights reserved. + # Copyright 2006 Sun Microsystems, Inc. Tous droits réservés. +@@ -11,6 +11,16 @@ + # Define public interface. + + SUNWprivate_1.1 { ++ global: ++ Java_sun_tools_attach_BSDVirtualMachine_checkPermissions; ++ Java_sun_tools_attach_BSDVirtualMachine_close; ++ Java_sun_tools_attach_BSDVirtualMachine_connect; ++ Java_sun_tools_attach_BSDVirtualMachine_sendQuitTo; ++ Java_sun_tools_attach_BSDVirtualMachine_socket; ++ Java_sun_tools_attach_BSDVirtualMachine_read; ++ Java_sun_tools_attach_BSDVirtualMachine_write; ++ Java_sun_tools_attach_BSDVirtualMachine_createAttachFile; ++ + local: + *; + }; diff --git a/java/jdk16/files/patch-j2se-services-com.sun.tools.attach.spi.AttachProvider b/java/jdk16/files/patch-j2se-services-com.sun.tools.attach.spi.AttachProvider new file mode 100644 index 000000000000..3d507474d0c4 --- /dev/null +++ b/java/jdk16/files/patch-j2se-services-com.sun.tools.attach.spi.AttachProvider @@ -0,0 +1,9 @@ +$FreeBSD$ + +--- ../../j2se/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider 1 Nov 2005 05:12:03 -0000 1.1.1.1 ++++ ../../j2se/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider 29 Jan 2009 08:13:19 -0000 +@@ -12,3 +12,4 @@ + #[solaris]sun.tools.attach.SolarisAttachProvider + #[windows]sun.tools.attach.WindowsAttachProvider + #[linux]sun.tools.attach.LinuxAttachProvider ++#[bsd]sun.tools.attach.BSDAttachProvider -- cgit