I'm a .NET-developer but recently I had to switch to Java for supporting one of our partners.
So I'm pretty new to Java. I'm extending the functionality of an existing application and I'm having an issue with my custom code to open the default email application and add attachments and recipients using JNative. I receive the following message in Eclipse after an application crash:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77e8e823, pid=7240, tid=8268
//TODO: change email to yours for testing
private final static String TO_ADDRESS = "me@company.com"; //not mine of course
private ArrayList<mapifiledesc> validAttachments = null;
private ArrayList<mapirecipdesc> validRecipients = null;
private Pointer ptrAttachments = null;
private Pointer ptrRecipients = null;
private HANDLE session = new HANDLE(0);
private MapiMessage mapiMessage = null;</mapirecipdesc></mapifiledesc>
//privatetransientLoggerlogger=Logger.getLogger(MailController.class);publicstaticvoidtest(){//TODO:changepathtoalocationwithsometextfilesStringpath="D:\\logs\\";ArrayList<String>attachments=newArrayList<>();//TODO:addsometextfilesasattachmentsattachments.add(path+"1406900592265_auditLog.log");attachments.add(path+"1406900592265_debugLog.log");attachments.add(path+"1406900592265_errorLog.log");attachments.add(path+"DebugAndHigher.log");attachments.add(path+"WarnAndHigher.log");attachments.add(path+"DebugAndHigher.log.1");MailControllermail=newMailController();ArrayList<String>to=newArrayList<>();to.add(TO_ADDRESS);ArrayList<String>cc=newArrayList<>();//cc.add(TO_ADDRESS);ArrayList<String>bcc=newArrayList<>();//bcc.add(TO_ADDRESS);mail.openEmailWithAttachmentsAndRecepients(to,cc,bcc,"Test","Some text\nand a second line\nattachments should be included",attachments);}privatevoidopenEmailWithAttachmentsAndRecepients(List<String>to,List<String>cc,List<String>bcc,Stringsubject,Stringbody,List<String>attachments){booleanaddAttachments=false;booleanaddRecipients=false;if(JOptionPane.showConfirmDialog(null,"Add attachments?","Mail test",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION){addAttachments=true;}if(JOptionPane.showConfirmDialog(null,"Add recipients?","Mail test",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION){addRecipients=true;}PointerlpszSubject=null;PointerlpszNoteText=null;PointerfilePath=null;try{//createaMapiMessagestructuremapiMessage=newMapiMessage();//***************************************************************************************************//Subjectandbody//***************************************************************************************************//setsubjectandmessagepointerslpszSubject=Pointer.createPointerFromString(subject);lpszNoteText=Pointer.createPointerFromString(body);//addthepointerstotheMapiMessagestructureforsubjectandbodymapiMessage.lpszSubject=lpszSubject.getPointer();mapiMessage.lpszNoteText=lpszNoteText.getPointer();//***************************************************************************************************//Attachments//***************************************************************************************************if(addAttachments)processAttachments(attachments);//***************************************************************************************************//Settherecipients//***************************************************************************************************if(addRecipients)processRecipients(to,cc,bcc);//***************************************************************************************************//Opentheemailandshowtotheuser//***************************************************************************************************//sendthemessageStringreturnError=SimpleMAPI.MAPISendMail(session,newLONG(0),mapiMessage,MAPIConstants.MAPI_DIALOG);System.out.println("MAPISendMail: "+returnError);System.out.println("If not 0, see value at http://msdn.microsoft.com/en-us/library/windows/desktop/hh707275(v=vs.85).aspx");}catch(IllegalAccessExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(Exceptione){e.printStackTrace();}finally{//logoffthesessionifpossibletry{SimpleMAPI.MAPILogoff(session,newLONG(0),0);}catch(IllegalAccessExceptione){e.printStackTrace();}catch(NativeExceptione){e.printStackTrace();}//cleanupattachmentpointerif(ptrAttachments!=null){try{ptrAttachments.dispose();ptrAttachments=null;}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}attachmentCleanup();//cleanuprecipientspointerif(ptrRecipients!=null){try{ptrRecipients.dispose();ptrRecipients=null;}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}recipientsCleanup(validRecipients);//cleanupbodypointerif(lpszNoteText!=null)try{lpszNoteText.dispose();}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}//cleanupsubjectpointerif(lpszSubject!=null)try{lpszSubject.dispose();}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}//cleanupmessageif(mapiMessage!=null)try{mapiMessage.getPointer().dispose();}catch(NativeExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}//cleanupfilepointerif(filePath!=null)try{filePath.dispose();}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}//unloadalllibrariesJNative.unLoadAllLibraries();}}privatevoidprocessRecipients(List<String>to,List<String>cc,List<String>bcc){//makingsurethatallarraysareinstantiatedif(to==null)to=newArrayList<String>();if(cc==null)cc=newArrayList<String>();if(bcc==null)bcc=newArrayList<String>();//Dependingontheemailprogram,theusermustallowaccessforthisroutine//Thisarraycontainstherecipientsthatarevalidif(validRecipients==null){validRecipients=newArrayList<>();}try{//processeachlistandputthevalidresultsinvalidRecipientsprocessOneListOfRecipients(to,MAPIConstants.MAPI_TO);processOneListOfRecipients(cc,MAPIConstants.MAPI_CC);processOneListOfRecipients(bcc,MAPIConstants.MAPI_BCC);//iftherearevalidrecipients,addthemtothemessage.ifno,showamessagewithnorecipientsif(validRecipients.size()>0){//allocatememorywiththesizeofMapiRecipDesc-objectforeachrecipient(to,cc,bcc),basicallyanarraypointer//whichholdsallthedataptrRecipients=Pointer.createPointer(validRecipients.size()*MapiRecipDesc.sizeOf());//foreachrecipient,weneedtosetthememoryintherightplaceinthememory(offset)intoffset=0;//loopthrougheachvalidrecipientfor(MapiRecipDesctmp:validRecipients){//copythebytesfromeachrecipientintherightplaceinthearrayJNative.setMemory(ptrRecipients.getPointer(),tmp.createPointer().getMemory(),offset,2*MapiRecipDesc.sizeOf()-1);//increaseoffsetforthenextrecipientoffset+=MapiRecipDesc.sizeOf();}//settherecipientstothemessagemapiMessage.nRecipCount=newLONG(validRecipients.size());mapiMessage.lpRecips=ptrRecipients.getPointer();}}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IllegalAccessExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}privatevoidprocessOneListOfRecipients(List<String>toList,inttypeOfRecipient)throwsNativeException,IllegalAccessException{LONGholder;intret;PointerptrToAddress;MapiRecipDescmapiRecipDesc;//loopthroughallrecipientsinthelistfor(StringsingleTo:toList){//newlongwith0->nullpointer,andwillbefilledinduringMAPIResolveNameholder=newLONG(0);//createapointertothestringptrToAddress=Pointer.createPointerFromString(singleTo);//ThenextlinecreatesaMapiRecipDesc-objectfromthestringpointerptrToAddressandreturnsapointer-value(LONG)//whichwillbestoredinholder.//Todothis,Outlook(orotherprogram),mightaskforpermissionstotheuser.//Ifdeniedorincaseoferror,thisrecipientisskippedret=SimpleMAPI.MAPIResolveName(session,newLONG(0),ptrToAddress,0,newLONG(0),holder);//ifandonlyifacreationwassuccessful,thenmodifythetypeandaddittothearrayofvalidrecipientsif(ret==MAPIConstants.SUCCESS_SUCCESS){//changetypetotherequestedtype(TO,CC,BCC)mapiRecipDesc=newMapiRecipDesc(holder.getValueFromPointer());mapiRecipDesc.ulRecipClass=newLONG(typeOfRecipient);//addtothevalidrecipientsarrayvalidRecipients.add(mapiRecipDesc);}mapiRecipDesc=null;ptrToAddress.dispose();}}privatevoidrecipientsCleanup(ArrayList<MapiRecipDesc>validRecipients){if(validRecipients!=null){//cleanupwhile(validRecipients.size()>0){try{validRecipients.get(0).getPointer().dispose();}catch(NativeExceptione){//failedtofreetheblocke.printStackTrace();}validRecipients.remove(0);}}}privatevoidprocessAttachments(List<String>attachments){//makingsurethatallarraysareinstantiatedif(attachments==null)attachments=newArrayList<String>();//Thisarraycontainstheattachmentsthatarevalidif(validAttachments==null){validAttachments=newArrayList<>();}try{//processeachlistandputthevalidresultsinvalidAttachmentsPointerptrAttachment;MapiFileDescmapiFileDesc;//loopthroughallattachmentsinthelistfor(Stringattachment:attachments){if((newFile(attachment).exists())){ptrAttachment=Pointer.createPointerFromString(attachment);mapiFileDesc=newMapiFileDesc();mapiFileDesc.lpszPathName=ptrAttachment.getPointer();mapiFileDesc.nPosition=newLONG(-1);mapiFileDesc.createPointer();validAttachments.add(mapiFileDesc);}}//iftherearevalidattachments,addthemtothemessage.ifno,showamessagewithnoattachmentsif(validAttachments.size()>0){//allocatememorywiththesizeofMapiFileDesc-objectforeachattachment,basicallyanarraypointer//whichholdsallthedataptrAttachments=Pointer.createPointer(validAttachments.size()*MapiFileDesc.sizeOf());//foreachattachment,weneedtosetthememoryintherightplaceinthememory(offset)intoffset=0;//loopthrougheachvalidattachmentfor(MapiFileDesctmp:validAttachments){//copythebytesfromeachattachmentintherightplaceinthearrayJNative.setMemory(ptrAttachments.getPointer(),tmp.createPointer().getMemory(),offset,2*MapiFileDesc.sizeOf()-1);//increaseoffsetforthenextrecipientoffset+=MapiFileDesc.sizeOf();}//settheattachmenttothemessagemapiMessage.nFileCount=newLONG(validAttachments.size());mapiMessage.lpFiles=ptrAttachments.getPointer();}}catch(NativeExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}privatevoidattachmentCleanup(){if(validAttachments!=null){//cleanupwhile(validAttachments.size()>0){try{validAttachments.get(0).getPointer().dispose();}catch(NativeExceptione){//failedtofreetheblocke.printStackTrace();}validAttachments.remove(0);}}}
}
When I run the code, No attachments, No recipients, then it always works.
From the moment I add attachments, it sometimes works +-80%. I cannot find the cause for the crash.
If I only add recipient, the application crashes 90% of the time on the first try.
If I add both, the application crashes always.
Does anyone have an idea what it could be?
Thanks in advance
Jo
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, I wrote this long long time ago and can't really remember too much.
Actually this looks strange to me:
//copy the bytes from each attachment in the right place in the arrayJNative.setMemory(ptrAttachments.getPointer(),tmp.createPointer().getMemory(),offset,2*MapiFileDesc.sizeOf()-1);
Why is the length paramter "2 * MapiFileDesc.sizeOf() - 1"? I also see this in my SimpleMAPI example but honestly I don't know why and why this works at all. I would expect simply "MapiFileDesc.sizeOf()". You are only allocating "validAttachments.size() * MapiFileDesc.sizeOf()" bytes of memory:
Ok, I was right. My example is not working with "2 * MapiRecipDesc.sizeOf() - 1", I get an EXCEPTION_ACCESS_VIOLATION like you do. Now I changed it to "MapiRecipDesc.sizeOf()" and it is working fine. So please do the same for recipients (MapiRecipDesc.sizeOf()) and attachments (MapiFileDesc.sizeOf()) and it should work for you, too.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm a .NET-developer but recently I had to switch to Java for supporting one of our partners.
So I'm pretty new to Java. I'm extending the functionality of an existing application and I'm having an issue with my custom code to open the default email application and add attachments and recipients using JNative. I receive the following message in Eclipse after an application crash:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77e8e823, pid=7240, tid=8268
It would be handy if you had some code:
package com.company.control;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.basicStructures.HANDLE;
import org.xvolks.jnative.misc.basicStructures.LONG;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.util.mapi.MAPIConstants;
import org.xvolks.jnative.util.mapi.SimpleMAPI;
import org.xvolks.jnative.util.mapi.structs.MapiFileDesc;
import org.xvolks.jnative.util.mapi.structs.MapiMessage;
import org.xvolks.jnative.util.mapi.structs.MapiRecipDesc;
public class MailController {
//TODO: change email to yours for testing
private final static String TO_ADDRESS = "me@company.com"; //not mine of course
private ArrayList<mapifiledesc> validAttachments = null;
private ArrayList<mapirecipdesc> validRecipients = null;
private Pointer ptrAttachments = null;
private Pointer ptrRecipients = null;
private HANDLE session = new HANDLE(0);
private MapiMessage mapiMessage = null;</mapirecipdesc></mapifiledesc>
}
When I run the code, No attachments, No recipients, then it always works.
From the moment I add attachments, it sometimes works +-80%. I cannot find the cause for the crash.
If I only add recipient, the application crashes 90% of the time on the first try.
If I add both, the application crashes always.
Does anyone have an idea what it could be?
Thanks in advance
Jo
Well, I wrote this long long time ago and can't really remember too much.
Actually this looks strange to me:
Why is the length paramter "2 * MapiFileDesc.sizeOf() - 1"? I also see this in my SimpleMAPI example but honestly I don't know why and why this works at all. I would expect simply "MapiFileDesc.sizeOf()". You are only allocating "validAttachments.size() * MapiFileDesc.sizeOf()" bytes of memory:
So I think that using the above JNative.setMemory() will result in a buffer overrun.
Please check the output of JNative.getMemoryAsString() on tmp.createPointer() with different length to see what is the proper size.
Ok, I was right. My example is not working with "2 * MapiRecipDesc.sizeOf() - 1", I get an EXCEPTION_ACCESS_VIOLATION like you do. Now I changed it to "MapiRecipDesc.sizeOf()" and it is working fine. So please do the same for recipients (MapiRecipDesc.sizeOf()) and attachments (MapiFileDesc.sizeOf()) and it should work for you, too.