Java在关闭具有堆损坏的WDropTargetContextPeerFileStream时崩溃

Java在关闭具有堆损坏的WDropTargetContextPeerFileStream时崩溃,java,windows,swing,heap-corruption,Java,Windows,Swing,Heap Corruption,我目前正在使用Swing DropTarget实现从Outlook到Swing(在Windows上)的拖放。因为Outlook拖放不会自动与Swing一起工作,所以我对它进行了调试,发现它在事件中使用了FileNameWnative。为了支持这一点,我使用以下代码: private静态最终字符串nativeFileNameW=“FileNameW”; 私有静态最终DataFlavor文件名wFlavor=新DataFlavor(InputStream.class,nativeFileNameW)

我目前正在使用Swing DropTarget实现从Outlook到Swing(在Windows上)的拖放。因为Outlook拖放不会自动与Swing一起工作,所以我对它进行了调试,发现它在事件中使用了
FileNameW
native。为了支持这一点,我使用以下代码:

private静态最终字符串nativeFileNameW=“FileNameW”;
私有静态最终DataFlavor文件名wFlavor=新DataFlavor(InputStream.class,nativeFileNameW);
public void installFileNameWFlavorIfWindows(DropTarget dt){
FlavorMap fm=dt.getFlavorMap();
if(!(SystemFlavorMap的fm实例)){
fm=SystemFlavorMap.getDefaultFlavorMap();
}
if(SystemFlavorMap的fm实例){
SystemFlavorMap sysFM=(SystemFlavorMap)fm;
sysFM.AddFavorForUnencodedNative(本地文件名w,文件名wFlavor);
sysFM.addUnencodedNativeForFlavor(fileNameWFlavor,nativeFileNameW);
dt.setvavormap(sysFM);
}
}
它似乎工作得很好,但我不确定这是否是正确的方法,因为我找不到关于这个问题的任何资源

在drop事件中,我现在可以在Swing组件上删除Outlook电子邮件时获得InputStream。我在drop方法中使用了以下代码(real方法更复杂,因为它还处理其他DataFlavor,但这里的示例可能会重现错误):

public void drop(DropTargetDropEvent dtde){
可转让转让转让=dtde.getTransferable();
布尔接受=假;
if(支持transfer.isdata(fileNameWFlavor)){
接受=正确;
dtde.acceptDrop(DnDConstants.ACTION\u COPY);
try(InputStream is=(InputStream)transfer.getTransferData(fileNameWFlavor)){
//用InputStream做些什么
}捕获(无支持的Lavore异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
数据删除完成(已接受);
}
我使用try with resource语句来确保流在drop事件之后关闭。我想关闭流,以确保在删除完成后没有打开的文件句柄或类似的本机资源,这些资源可能会受到限制。 从Outlook拖放的InputStream是
WDropTargetContextPeerFileStream
的一个实例,当调用close方法时,它在本机方法
freeStgMedium
中崩溃,这将释放本机windows数据结构

我在命令行上没有得到任何错误输出。
程序终止时出现错误代码
-1073740940
,这似乎表明存在堆损坏错误

我有什么遗漏吗?这个InputStream是否不应该关闭,或者之前是否存在错误

我正在使用来自Azul的JDK,Zulu 8.48.0.53(Java 8u265)。
我还用Zulu11、OracleJava8和一个Redhat构建的OpenJDK8进行了尝试,所有这些都以同样的方式失败

更新: 我想我找到了这个bug,找到了JDK本机代码,获得了数据

JDK代码在堆栈上创建一个STGMEDIUM对象,并将指向该对象的指针传递给Windows方法IDataObject::GetData()。此方法将其数据写回
STGMEDIUM*
参数。
这应该不是问题,因为此Windows函数的所有示例都以相同的方式执行。但是,Outlook似乎没有初始化成员变量
IUnknown*STGMEDIUM::pUnkForRelease
,而是依赖调用者零填充数据结构(或者Outlook有错误)。
当Java释放本机资源时,它会调用
ReleaseStgMedium
,如果指针不是
NULL
,它会尝试在
pUnkForRelease
指针上调用
Release
,从而导致错误

现在,我只是不关闭输入流,让FileHandle泄漏,这不是最优的,但我没有看到任何其他解决方案


如果我找到了这个错误的真正解决方案,我会在这里写一个更新/答案。

FileNameW
听起来你并没有收到一个特殊的项目,只是收到了一个文件名。您是否尝试通过内置的方式接收它?默认情况下,FileNameW本机不与任何DataFlavor关联,否则我就不需要这样做(完整的代码更喜欢使用javaFileListFlavor,因为它还支持从其他电子邮件客户端进行的删除,所有这些客户端都可以使用javaFileListFlavor)。我得到了一个工作输入流,可以使用数据,这是一个正确的Outlook邮件。唯一的问题是,我似乎无法关闭InputStream,因为一些本机资源在被释放时崩溃。我从未见过
SystemFlavorMap
的任何(真实的)示例代码,很长时间以来一直在想是否有人在实践中使用过它。因此,当您发现一个以前没有人注意到的bug时,我不会感到惊讶,因为从来没有人尝试过。我也不知道,我只是通过检查我得到的是什么类型的FlavorMap(因为FlavorMap本身不提供setter方法)来编写代码并使用它。但是我相信带有FlavorMap的部分工作正常,因为我得到了一个InputStream,它似乎创建了一个WDropTargetContextPeer,但是一些本地数据似乎不正确,我不知道是什么。如果我能调试这个本地代码,你知道吗?我会看看是否能找到本机代码,并找出它应该做什么,但我对自己使用windows库的技能不是很有信心