08-22-2012 12:16 AM
Hi... I'll start by saying that this is my first post and I'm incredibly new to working with Blackberry application development. The app I'm working with is home grown and has been in use for several years. We're deploying new Bold 9900's to our employees and I'm trying to update the app to be compatible with OS 7.1. I've loaded the project in Eclipse, successfully signed and built everything, and installed on my test phone.
The app receives data and instructions via email attachments and identifies the emails it needs to work with by the subject line... right now the app is correctly triggering when the emails are received but when it attempts to get the attachment things go south. I checked the phone's event log and I'm seeing two error events which are as follows:
(Error referencing the application)
Name: PrecisionCollector
GUID: 3401882cc7a5a956
Time: Aug 21, 2012 22:45:21
Exception caugth in PrecicionMessage.run(): java.lang.Exception: Could not obtain attachment from Precision Message
(Error that comes before the application error above)
Name: ControlledAccessException
GUID: 9c3cd62e3320b498
Time: Aug 21, 2012 22:45:21
Unauthorized attempt to attach to this application
net_rim_cldc-10(4EDC0D64)
Application
getApplication
0x3C1D
net_rim_bbapi_mailv2(4EDC1314)
Session
isMailServiceAccessible
0x6391
net_rim_bbapi_mailv2(4EDC1314)
Session
isMailServiceAccessible
0x63F8
net_rim_bbapi_mailv2(4EDC1314)
Session
assertPersonalLiabilityPermssion
0x61CA
net_rim_bbapi_mailv2(4EDC1314)
Session
getInstance
0x6272
net_rim_bbapi_mailv2(4EDC1314)
Folder
<init>
0x2088
net_rim_bbapi_mailv2(4EDC1314)
Folder
<init>
0x2021
net_rim_bbapi_mailv2(4EDC1314)
ListenerManager
doDispatch
0x2D99
net_rim_bbapi_mailv2(4EDC1314)
ListenerManager
dispatchFolderEvent
0x2E9A
net_rim_bbapi_mailv2(4EDC1314)
ListenerManager
elementRemoved
0x2800
net_rim_cldc-5(4EDC0D64)
CollectionListenerManager
fireElementRemoved
0x2EF4
net_rim_bb_messaging(4EDC0DEE)
MergedCollection
elementRemoved
0x3EC3
net_rim_cldc-5(4EDC0D64)
CollectionListenerManager
fireElementRemoved
0x2EF4
net_rim_bb_messaging-2(4EDC0DEE)
SortedCollection
remove
0x2930
net_rim_bb_messaging-2(4EDC0DEE)
PersistedSortedCollection
remove
0x21EA
net_rim_bb_email-8(4EDC12E7)
PersistedSortedCollectionHook
remove
0x5EE2
net_rim_bb_messaging-2(4EDC0DEE)
SortedCollection
remove
0x2BE4
net_rim_bb_email(4EDC12E7)
EmailMessageModelImpl
delete
0x90BD
net_rim_bb_email(4EDC12E7)
EmailMessageModelImpl
delete
0x873E
net_rim_bb_email(4EDC12E7)
EmailMessageModelImpl
perform
0x52E8
net_rim_bbapi_mailv2(4EDC1314)
Folder
deleteMessage
0x1D6B
PrecisionCollector(50344FEE)
IncomingMail
messagesAdded
0x4E88
net_rim_bbapi_mailv2-1(4EDC1314)
FolderEvent
dispatch
0x63
net_rim_bbapi_mailv2(4EDC1314)
ListenerManager$AsyncFolderListener$Callback
execute
0x33AB
net_rim_cldc-7(4EDC0D64)
ExternalListener$SynchronizedCallback
run
0x372E
net_rim_cldc-7(4EDC0D64)
ProxyRunnableQueue
run
0xB58F
net_rim_cldc-2(4EDC0D64)
Thread
run
0xAAC9
If anyone can help direct me on how to handle this I'd be incredibly grateful... The app has worked with the current coding from OS v4 through v6 so I'm not sure what's different with 7.1 that would cause this issue. Also, I checked the application's permissions on the phone and everything is set to Allow.
Thanks in advance,
-John
Solved! Go to Solution.
08-22-2012 02:36 AM
08-22-2012 02:50 AM
Thanks for posting! The phone definitely isn't encrypted. The following is the code behind PrecisionMessage.run()
import java.io.ByteArrayInputStream; import java.io.DataInputStream; import javax.microedition.rms.RecordEnumeration; import javax.microedition.rms.RecordFilter; import javax.microedition.rms.RecordStore; import net.rim.blackberry.api.mail.Folder; import net.rim.blackberry.api.mail.Message; import net.rim.blackberry.api.mail.Multipart; import net.rim.blackberry.api.mail.SupportedAttachmentPart; import net.rim.device.api.system.ApplicationManager; import net.rim.device.api.system.DeviceInfo; import net.rim.device.api.system.EventLogger; import net.rim.device.api.util.IntHashtable; import net.rim.device.api.xml.parsers.DocumentBuilder; import net.rim.device.api.xml.parsers.DocumentBuilderFact ory; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; class PrecisionMessage implements Runnable { // dd update : we need to exclude meters of this from display on device public static int PMPDiplayMeterTypeId = 807; Message EmailMessage; String Log; PrecisionCollector _theCollector; public PrecisionMessage(Message emailMessage, PrecisionCollector theCollector) { EmailMessage = emailMessage; _theCollector = theCollector; Log = new String(); } public void run() { try { String XMLString = null; Object content = EmailMessage.getContent(); int length = ((Multipart)content).getCount(); for(int i=0; i < length; i++) { Object messagePart = ((Multipart)content).getBodyPart(i); if(messagePart instanceof SupportedAttachmentPart) { SupportedAttachmentPart attachment = (SupportedAttachmentPart) messagePart; XMLString = new String((byte[])attachment.getContent()); XMLString.replace('\0', ' '); } } if(XMLString == null) { try { new OutgoingMail(DataStore._ConfigValues.NotifyEmail, "Handset Error On: " + Integer.toHexString(DeviceInfo.getDeviceId()), "A malformed Precision XML Message was received on this device", false); } catch(Exception e) { System.out.println("Exception caught in IncomingMail.MessageAdded(): " + e.toString()); e.printStackTrace(); } throw new Exception("Could not obtain attachment from Precision Message"); } Log += "Attempting to Parse Precision Message: " + XMLString + "\n"; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new ByteArrayInputStream(XMLString.getBytes())); Location loc; Equipment equip; Meter meter; Reason reason; MeterType meterType; NamedNodeMap nodeMap; RecordEnumeration dataset; byte[] record; int retval; RecordStore EquipmentStore = DataStore._EquipmentStore; RecordStore MeterStore = DataStore._MeterStore; RecordStore LocationStore = DataStore._LocationStore; if(document.getElementsByTagName("LocAssignment"). getLength() > 0) { loc = new Location(); Log += "Loc1\n"; loc.ID = Integer.parseInt(document.getElementsByTagName("Lo cID").item(0).getFirstChild().getNodeValue()); Log += "Loc2\n"; loc.Number = document.getElementsByTagName("Number").item(0).ge tFirstChild().getNodeValue(); Log += "Loc3\n"; try { loc.Name = document.getElementsByTagName("Name").item(0).getF irstChild().getNodeValue(); } catch(Exception exception) { loc.Name = ""; } Log += "Loc4\n"; try { loc.Attn = document.getElementsByTagName("Attn").item(0).getF irstChild().getNodeValue(); } catch(Exception exception) { loc.Attn = ""; } Log += "Loc5\n"; try { loc.Street = document.getElementsByTagName("Street").item(0).ge tFirstChild().getNodeValue(); } catch(Exception exception) { loc.Street = ""; } Log += "Loc6\n"; try { loc.City = document.getElementsByTagName("City").item(0).getF irstChild().getNodeValue(); } catch(Exception exception) { loc.City = ""; } Log += "Loc7\n"; try { loc.State = document.getElementsByTagName("State").item(0).get FirstChild().getNodeValue(); } catch(Exception exception) { loc.State = ""; } Log += "Loc8\n"; try { loc.Zip = document.getElementsByTagName("Zip").item(0).getFi rstChild().getNodeValue(); } catch(Exception exception) { loc.Zip = ""; } Log += "Loc9\n"; Log += "Attempting to parse Equipment"; length = document.getElementsByTagName("Equip").getLength() ; for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("Equip").item(i).get Attributes(); // dd update : include Enabled Automated Collection features equip = new Equipment(); try { equip.ID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); equip.EquipmentID = equip.ID; equip.Number = nodeMap.getNamedItem("Num").getNodeValue(); equip.SN = nodeMap.getNamedItem("SN").getNodeValue(); equip.Desc = nodeMap.getNamedItem("Desc").getNodeValue(); equip.Building = nodeMap.getNamedItem("Building").getNodeValue(); equip.Floor = nodeMap.getNamedItem("Floor").getNodeValue(); equip.Cube = nodeMap.getNamedItem("Cube").getNodeValue(); equip.Contact = nodeMap.getNamedItem("Contact").getNodeValue(); equip.PrevReasonNotCollectedID = Integer.parseInt(nodeMap.getNamedItem("Reason").ge tNodeValue()); equip.PrevRemarks = nodeMap.getNamedItem("Remarks").getNodeValue(); equip.WalkOrder = Integer.parseInt(nodeMap.getNamedItem("Order").get NodeValue()); if (nodeMap.getNamedItem("DutyCycle").getNodeValue() == "true") equip.DutyCycle =true; else equip.DutyCycle = false; equip.IPAddress = nodeMap.getNamedItem("IPAddress").getNodeValue(); // this is obsolate now, because we assume that all pieces of equipment // can be enabled for automatic electronic collection // so, I will comment it, but leave in case we need it in future int intBool = Integer.parseInt(nodeMap.getNamedItem("ElectronicC ollection").getNodeValue()); equip.ElectronicCollection = true; // we will assume correct IP address if field length > 0 equip.EnabledElectronicColl = (equip.IPAddress.length() > 0); equip.EnableItInNextMsg = false; } catch(Exception ex) { Log += "\nException in parsing Equipment\n"; EventLogger.logEvent(0x3401882cc7a5a956L, ("Exception in processing incoming mail, in reading required properties : " + ex.toString()).getBytes(), EventLogger.SEVERE_ERROR); System.out.println("Exception in processing incoming mail, in reading required properties : " + ex.toString() ); } // end of dd update equip.ReasonNotCollectedID = 0; equip.Remarks = ""; equip.Done = false; equip.LocID = loc.ID; dataset = EquipmentStore.enumerateRecords(new GetEquip(equip.ID), null, false); if(dataset.numRecords() != 0) { Log += "Equipment ID: " + equip.ID + " already exists and will not be added\n"; } else { record = equip.toByteArray(); retval = EquipmentStore.addRecord(record, 0, record.length); Log += "Equipment Added, Record ID: " + retval + "\nEquipment Record Size: " + EquipmentStore.getRecordSize(retval) + "\nAvailable Space in Equipment Store: " + EquipmentStore.getSizeAvailable() + "\n"; } } Log += "Attempting to parse Meters\n"; length = document.getElementsByTagName("Meter").getLength() ; for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("Meter").item(i).get Attributes(); meter = new Meter(); meter.EquipID = Integer.parseInt(nodeMap.getNamedItem("EquipID").g etNodeValue()); meter.ID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); meter.TypeID = Integer.parseInt(nodeMap.getNamedItem("Type").getN odeValue()); meter.High = Integer.parseInt(nodeMap.getNamedItem("High").getN odeValue()); meter.Low = Integer.parseInt(nodeMap.getNamedItem("Low").getNo deValue()); meter.Date = ""; meter.EquipNum = ""; meter.Actual = -1; dataset = MeterStore.enumerateRecords(new GetMeter(meter.ID), null, false); if(dataset.numRecords() != 0) { Log += "Meter ID: " + meter.ID + " already exists and will not be added\n"; } else { // dd update : to skip meters of PMPDisplayMeterTypeId if(meter.TypeID != PrecisionMessage.PMPDiplayMeterTypeId) { record = meter.toByteArray(); retval = MeterStore.addRecord(record, 0, record.length); Log += "Meter Added, ID: " + retval + "\nMeter Record Size: " + MeterStore.getRecordSize(retval) + "\nAvailable Space in Meter Store: " + MeterStore.getSizeAvailable() + "\n"; } else { // Log += "Meter of PMPDisplay type skipped \n"; } } } dataset = LocationStore.enumerateRecords(new GetLoc(loc.ID), null, false); if(dataset.numRecords() != 0) { Log += "Location already exists - Updating the Equipment List\n"; ApplicationManager.getApplicationManager().postGlo balEvent(0xf0985f7efa70795fL,0,0,null,null); // UpdateEquipmentList } else { loc.NextWalkOrder = 1; record = loc.toByteArray(); retval = LocationStore.addRecord(record, 0, record.length); Log += "Location Added Successfully, ID: " + retval + "\n"; ApplicationManager.getApplicationManager().postGlo balEvent(0xcf059df4c8b03703L,0,0,null,null); // UpdateLocation } } else if(document.getElementsByTagName("ControlMsg").get Length() > 0) { Log += "Attempting to parse handset control message\n"; RecordStore ReasonStore = DataStore._ReasonStore; RecordStore MeterTypeStore = DataStore._MeterTypeStore; DataStore.SaveConfigValues(document.getElementsByT agName("ServerEmail").item(0).getFirstChild().getN odeValue(), document.getElementsByTagName("NotifyEmail").item( 0).getFirstChild().getNodeValue(), document.getElementsByTagName("WSUrl").item(0).get FirstChild().getNodeValue(), document.getElementsByTagName("DeviceNumber").item (0).getFirstChild().getNodeValue()); try { String debugLevel = document.getElementsByTagName("LogLevel").item(0). getFirstChild().getNodeValue(); if(debugLevel.toUpperCase().indexOf("DEBUG") != -1) EventLogger.setMinimumLevel(EventLogger.DEBUG_INFO ); else if(debugLevel.toUpperCase().indexOf("INFORMATION") != -1) EventLogger.setMinimumLevel(EventLogger.INFORMATIO N); else if(debugLevel.toUpperCase().indexOf("WARNING") != -1) EventLogger.setMinimumLevel(EventLogger.WARNING); } catch(Exception exception) { } dataset = ReasonStore.enumerateRecords(null, null, false); while(dataset.hasNextElement()) { int id = dataset.nextRecordId(); reason = new Reason(id, ReasonStore.getRecord(id)); Log += "About to Delete ReasonNotCollected Record ID: " + id + " -- Reason ID: " + reason.ID + " -- Display Name: " + reason.getDisplayName() + "\n"; ReasonStore.deleteRecord(id); } length = document.getElementsByTagName("NotCollectedReason" ).getLength(); for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("NotCollectedReason" ).item(i).getAttributes(); reason = new Reason(); reason.ID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); reason.Desc = nodeMap.getNamedItem("Desc").getNodeValue(); reason.ConseqUse = !nodeMap.getNamedItem("ConseqUse").getNodeValue(). equals("0"); record = reason.toByteArray(); retval = ReasonStore.addRecord(record, 0, record.length); Log += "Added ReasonNotCollected, Record ID: " + retval + "\n"; } dataset = MeterTypeStore.enumerateRecords(null, null, false); while(dataset.hasNextElement()) { int id = dataset.nextRecordId(); meterType = new MeterType(id, MeterTypeStore.getRecord(id)); Log += "About to Delete MeterType Record ID: " + id + " -- MeterType ID: " + meterType.ID + " -- Display Name: " + meterType.getDisplayName() + "\n"; MeterTypeStore.deleteRecord(id); } length = document.getElementsByTagName("MeterType").getLeng th(); for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("MeterType").item(i) .getAttributes(); meterType = new MeterType(); meterType.ID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); meterType.Type = nodeMap.getNamedItem("Type").getNodeValue(); meterType.Desc = nodeMap.getNamedItem("Desc").getNodeValue(); record = meterType.toByteArray(); retval = MeterTypeStore.addRecord(record, 0, record.length); Log += "Added meter type, ID: " + retval + "\n"; } ApplicationManager.getApplicationManager().postGlo balEvent(0xd0b8f0e6b3e2bc80L,0,0,null,null); // UpdateHandsetControl } else if(document.getElementsByTagName("ReleaseEquip").g etLength() > 0) { IntHashtable EquipHash = new IntHashtable(); // Put all of the equipment into a hash dataset = EquipmentStore.enumerateRecords(null, null, false); while(dataset.hasNextElement()) { int id = dataset.nextRecordId(); equip = new Equipment(id, EquipmentStore.getRecord(id)); EquipHash.put(equip.ID, equip); } Log += "Abut to get release equipment list\n"; length = document.getElementsByTagName("Equip").getLength() ; for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("Equip").item(i).get Attributes(); int EquipID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); try { equip = (Equipment)EquipHash.get(EquipID); EquipmentStore.deleteRecord(equip.RecordID); } catch(Exception e) { Log += "Equipment ID: " + EquipID + " not found -- Cannot be unassigned\n"; e.printStackTrace(); } } // Do the cleanup of Orphaned Locations, Equipment, and Meters Here DataStore.CleanupDB(); ApplicationManager.getApplicationManager().postGlo balEvent(0xcf059df4c8b03703L,0,0,null,null); // UpdateLocation ApplicationManager.getApplicationManager().postGlo balEvent(0xf0985f7efa70795fL,0,0,null,null); // UpdateEquipmentList } else if(document.getElementsByTagName("AMCEquipments"). getLength() > 0) { Log += "Parsing enabled equipments:\n"; int locationID = Integer.parseInt( document.getElementsByTagName("LocID").item(0).get FirstChild().getNodeValue()); Log += "Location id:" + locationID + "\n"; Log += "Attempting to parse enabled equipments\n"; int equipmentCount = document.getElementsByTagName("EnabledEq").getLeng th(); for(int i=0; i < equipmentCount; i++){ nodeMap = document.getElementsByTagName("EnabledEq").item(i) .getAttributes(); equip = new Equipment(); try { equip.ID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); equip.EquipmentID = equip.ID; equip.Number = nodeMap.getNamedItem("Num").getNodeValue(); equip.Done = true; equip.LocID = locationID; equip.displayInUI = false; } catch(Exception ex){ Log += "\nException in parsing Equipment\n"; EventLogger.logEvent(0x3401882cc7a5a956L, ("Exception in processing incoming mail, in reading required properties : " + ex.toString()).getBytes(), EventLogger.SEVERE_ERROR); System.out.println("Exception in processing incoming mail, in reading required properties : " + ex.toString() ); } dataset = EquipmentStore.enumerateRecords(new GetEquip(equip.ID), null, false); if(dataset.numRecords() != 0) { Log += "Equipment ID: " + equip.ID + " already exists and will not be added\n"; } else { record = equip.toByteArray(); retval = EquipmentStore.addRecord(record, 0, record.length); Log += "Equipment Added, Record ID: " + retval + "\nEquipment Record Size: " + EquipmentStore.getRecordSize(retval) + "\nAvailable Space in Equipment Store: " + EquipmentStore.getSizeAvailable() + "\n"; } } ApplicationManager.getApplicationManager().postGlo balEvent(0xf0985f7efa44595fL,0,0,null,null); // UpdateEnabled } else if(document.getElementsByTagName("RecallEquip").ge tLength() > 0) { IntHashtable AllEquipHash = new IntHashtable(); IntHashtable RecallEquipHash = new IntHashtable(); // Put all of the equipment into a hash dataset = EquipmentStore.enumerateRecords(null, null, false); // Put all of the equipment into a hash dataset = EquipmentStore.enumerateRecords(null, null, false); while(dataset.hasNextElement()) { int id = dataset.nextRecordId(); equip = new Equipment(id, EquipmentStore.getRecord(id)); AllEquipHash.put(equip.ID, equip); } Log += "Abut to get release equipment list\n"; length = document.getElementsByTagName("Equip").getLength() ; for(int i=0; i < length; i++) { nodeMap = document.getElementsByTagName("Equip").item(i).get Attributes(); int EquipID = Integer.parseInt(nodeMap.getNamedItem("ID").getNod eValue()); try { equip = (Equipment)AllEquipHash.get(EquipID); RecallEquipHash.put(equip.ID, equip); } catch(Exception e) { Log += "Equipment ID: " + EquipID + " not found -- Cannot be unassigned\n"; e.printStackTrace(); } } // Do the cleanup of Orphaned Locations, Equipment, and Meters Here DataStore.RecallEquipment(RecallEquipHash); DataStore.CleanupDB(); ApplicationManager.getApplicationManager().postGlo balEvent(0xcf059df4c8b03703L,0,0,null,null); // UpdateLocation ApplicationManager.getApplicationManager().postGlo balEvent(0xf0985f7efa70795fL,0,0,null,null); // UpdateEquipmentList } else { new OutgoingMail(DataStore._ConfigValues.NotifyEmail, "Handset Error On: " + Integer.toHexString(DeviceInfo.getDeviceId()), "A malformed Precision XML Message was received on this device", false); } EventLogger.logEvent(0x3401882cc7a5a956L, Log.getBytes(), EventLogger.DEBUG_INFO); } catch(Exception exception) { EventLogger.logEvent(0x3401882cc7a5a956L, ("Exception caugth in PrecicionMessage.run(): " + exception.toString() + "\n\nLog: " + Log).getBytes(), EventLogger.SEVERE_ERROR); exception.printStackTrace(); System.out.println(exception.toString()); } Folder messageFolder = EmailMessage.getFolder(); messageFolder.deleteMessage(EmailMessage); _theCollector.ProcessPrecisionMsg(true); } }
08-22-2012 05:50 AM
I have a theory here, but perhaps Simon or someone else will shot it down. But I suspect the problem here
messageFolder.deleteMessage(EmailMessage);
First thing to note from the log (and I agree with Simon, good work getting together all this info for us to look at!), is that you are apparently running under control of a process in the Mail application, not your application, presumably this process:
net_rim_bbapi_mailv2
I think that over the years, RIM have been tightening up what you can with Listeners. The problem is that any application can add a listener, and then that listener acquires the permissions of the app it is running under, which perhaps give the listener the opportunity to do things that the user has not specifically given it the right to do. One of these things might be the right to delete messages, so in later OS levels, this might not be granted. So you need to move this code to your own application, and make sure that this application does have permission to delete messages.
Anyway, as a first test, remove the delete and see if the processing them works OK (aside from the message not being deleted of course). Then we can look at swapping into your own application to do the delete, which I would recommend you do using a Global Event.
In fact in general I would actually recommend that you move all of the processing to your own application, but that might be a big change that is not needed to get it working.
Hope this makes sense.
08-22-2012 09:10 AM
08-22-2012 11:53 AM
Based on your feedback I went ahead and commented out the line messageFolder.deleteMessage(EmailMessage); then repackaged and pushed to the phone. I'm getting the same errors. Is there a way that I could post a zip file of the entire project on here for you to look at? Would that be helpful or is that asking too much? I really don't want to overstep my bounds here...?
08-22-2012 12:00 PM
08-22-2012 12:03 PM
May we see the log from the error?
You might consider the RIM incident support to help you here:
08-22-2012 12:06 PM
I'm still trying to get the simulator working. My dev enviornment is setup in a VMware VM running Windows Server 08 R2 Standard... the simulator never finishes booting up when I try to start it in the VM... it'll get to about 80% on the boot screen progress indicator then freeze. Right now I'm testing 100% on the phone by repackaging each time, uploading to my BES and repushing to the phone.
I'll try to get the sim working this afternoon.
08-22-2012 12:09 PM
In my first post I put the two error log entries in there. The same error is still throwing. I just uninstalled the app but can reinstall real quick and recopy the errors. Give me about 10 mins and I'll repost.
Thanks!