Saving Timesheet Entry causes Error in Eclipse IDE but not web UI
I have an application to pull timesheet data from RTC, allow the user to add time and post the information back into RTC. While developing, I used the web UI to validate my results, and when using the web UI, I can see the timesheets being saved and the data displays. Now I am trying to use the Eclipse RTC plugin to perform the same functionality. I can enter the time on a task without a problem in Eclipse. Once the application pulls the timesheet and the user makes the changes and saves, I can see it in the web UI, but the Eclipse interface gets an error. The visible error is "Error running operation 'Unnamed'" I then looked in the log and see the stacktrace below. I have also attached the save code. below the stack trace. Does anyone have an idea as to why I am getting the error and what I can do to resolve it?
java.lang.NullPointerException
at com.ibm.team.tpt.ide.ui.timesheet.internal.TimeSheetEntryPartIDE$3.widgetSelected(TimeSheetEntryPartIDE.java:261)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
public void processTimeSheets (List<RTCTaskEntries> inTasks, RTCClient client, String username, Date startDate) throws Exception {// Declaration section for reusable objects/variablesif (!TeamPlatform.isStarted()) {TeamPlatform.startup();}service = TeamPlatform.getTeamRepositoryService();teamRepository = service.getTeamRepository(client.getBaseURL());teamRepository.registerLoginHandler(new LoginHandler(client.username, client.password));teamRepository.login(monitor);itemManager = teamRepository.itemManager();processClient = (IProcessClientService) teamRepository.getClientLibrary(IProcessClientService.class);uri = URI.create(client.projectName.replaceAll(" ", "%20"));projectArea = (IProjectArea) processClient.findProcessArea(uri, null, null);queryClient = (IQueryClient) teamRepository.getClientLibrary(IQueryClient.class);wicService = (IWorkItemClient) teamRepository.getClientLibrary(IWorkItemClient.class);wcm = wicService.getWorkItemWorkingCopyManager();try {IWorkItemHandle wiHandle = null;IWorkItem wi = null;WorkItemWorkingCopy wc = null;ITimeSheetEntry tseRec; // Not able to initialize to null due to object type.IItemHandle refItem = null;RTCTaskEntries inItem = null;
// Loop through the task/timesheet entries and post them. Do not check to see if there were changes, just update everythingIterator<RTCTaskEntries> inTasksIterator = inTasks.iterator();while (inTasksIterator.hasNext()) {inItem = inTasksIterator.next();
// Query where clause parameters. Look for the project we got in the incoming list.IQueryableAttribute idAttribute = findAttribute(teamRepository, projectArea, IWorkItem.ID_PROPERTY, null);Expression idExpression = new AttributeExpression(idAttribute, AttributeOperation.EQUALS, inItem.getId());Term term = new Term(Operator.AND);term.add(idExpression);IQueryResult<IResolvedResult<IWorkItem>> results = queryClient.getResolvedExpressionResults(projectArea, term, IWorkItem.FULL_PROFILE);
if (!results.hasNext(monitor)) {// There is no project of the type coming in. This is an error condition and should never occur.logger.error("Task recieved which we do not recognize.");}else {// Get a working Item so we can make changes. Need a Copy Manager object to create it so we can save.wi = results.next(monitor).getItem();wiHandle = (IWorkItemHandle) wi.getItemHandle();wcm.connect(wiHandle, IWorkItem.FULL_PROFILE, monitor);wc = wicService.getWorkItemWorkingCopyManager().getWorkingCopy(wiHandle);// Get item from WC to mess with so we can use the WC.Save function to write it backIWorkItem wiCopy = wc.getWorkItem();IWorkItemHandle copyHandle = (IWorkItemHandle) wiCopy.getItemHandle();// Move the new duration into the DBwiCopy.setDuration(new Double(inItem.getEstimate()*60*60*1000).longValue());// Ensure the epmsBucketId is saved.if (inItem.getEpmsBucketId() != null) {for (IAttributeHandle epmsHandle : wiCopy.getCustomAttributes()) {IAttribute epmsAttrib = (IAttribute) itemManager.fetchCompleteItem(epmsHandle, IItemManager.REFRESH, monitor);if (epmsAttrib.getIdentifier() == "com.usaa.team.attribute.epmsBucketId") {wiCopy.removeCustomAttribute(epmsAttrib);wc.save(monitor);}}IAttribute epmsAttribId = wicService.findAttribute(projectArea, "com.usaa.team.attribute.epmsBucketId", monitor);wiCopy.setValue(epmsAttribId, inItem.getEpmsBucketId());}// If there are time sheet entries post themIterator<RTCTimeSheet> inTimeIterator = inItem.getTimeEntries().iterator();while (inTimeIterator.hasNext()) {RTCTimeSheet inTs = inTimeIterator.next();// Iterate through the references and check each time sheet entry to see if it matches the one we have.IWorkItemReferences itemReference = wc.getReferences();List<IReference> times = itemReference.getReferences(WorkItemEndPoints.WORK_TIME);boolean found = false;for (IReference workTimes : times) {if (workTimes.isItemReference()) {refItem = ((IItemReference) workTimes).getReferencedItem();if (refItem instanceof ITimeSheetEntryHandle) {tseRec = (ITimeSheetEntry) itemManager.fetchCompleteItem(refItem, IItemManager.REFRESH, monitor);if (tseRec.getItemId().equals(inTs.getTimeSheetId())) {// match foundfound = true;ITimeSheetEntry newEntry = wicService.createTimeSheetEntry(projectArea.getProjectArea());newEntry.setHoursSpent(inTs.getHoursSpent());newEntry.setTimeSpent(new Duration(new Double(inTs.getHoursSpent()*1000*60*60).longValue()));newEntry.setStartDate(tseRec.getStartDate());newEntry.setCreator(tseRec.getCreator());newEntry.setWorkType(tseRec.getWorkType());newEntry.setTimeCode(tseRec.getTimeCode());newEntry.setTimeCodeId(tseRec.getTimeCodeId());IItemReference tsRef = IReferenceFactory.INSTANCE.createReferenceToItem(newEntry);itemReference.remove(workTimes);wc.getDependentItems().remove((IAuditableHandle) refItem);wc.save(monitor);itemReference.add(WorkItemEndPoints.WORK_TIME, tsRef);wc.getDependentItems().add(newEntry);// Save the changes to the Work Item.IDetailedStatus result = wc.save(monitor);if (!result.isOK()) {switch (result.getCode()) {case IDetailedStatus.INFO: {logger.info(result.getMessage()); break;}case IDetailedStatus.WARNING: {logger.warn(result.getMessage()); break;}case IDetailedStatus.ERROR: {logger.error(result.getMessage()); break;}}}}}}}if (!found) {// we did not find the record in the DB and must enter it newITimeSheetEntry newEntry = wicService.createTimeSheetEntry(projectArea.getProjectArea());newEntry.setHoursSpent(inTs.getHoursSpent());newEntry.setTimeSpent(new Duration(new Double(inTs.getHoursSpent()*1000*60*60).longValue()));newEntry.setStartDate(inTs.getStartDate());newEntry.setCreator(getOwner(username, teamRepository));newEntry.setWorkType(Identifier.create(ILiteral.class, "Task"));newEntry.setTimeCode("Default");newEntry.setTimeCodeId("Default");IItemReference tsRef = IReferenceFactory.INSTANCE.createReferenceToItem(newEntry);itemReference.add(WorkItemEndPoints.WORK_TIME, tsRef);wc.getDependentItems().add(newEntry);// Save the changes to the Work Item.IDetailedStatus result = wc.save(monitor);if (!result.isOK()) {switch (result.getCode()) {case IDetailedStatus.INFO: {logger.info(result.getMessage()); break;}case IDetailedStatus.WARNING: {logger.warn(result.getMessage()); break;}case IDetailedStatus.ERROR: {logger.error(result.getMessage()); break;}}}}}// Save the changes to the Work Item.IDetailedStatus result = wc.save(monitor);if (!result.isOK()) {switch (result.getCode()) {case IDetailedStatus.INFO: {logger.info(result.getMessage()); break;}case IDetailedStatus.WARNING: {logger.warn(result.getMessage()); break;}case IDetailedStatus.ERROR: {logger.error(result.getMessage()); break;}}}}}}catch (Exception ex) {logger.error(ex.getMessage());throw ex;}finally {teamRepository.logout();wcm = null;wicService = null;queryClient = null;projectArea = null;uri = null;processClient = null;itemManager = null;teamRepository = null;service = null;}}
Comments
Millard Ellingsworth
FORUM ADMINISTRATOR / JAZZ DEVELOPER May 22 '13, 6:46 p.m.To clarify, it sounds like the data is being saved fine (you can see the updates from the web UI) but when you try to view the updates from the Eclipse UI, you see this error. Correct? Does this only happen if the Eclipse UI has the timesheet open when you update it externally or is the timesheet in Eclipse "broken" forever after your update? And what RTC version (server and Eclipse client)?
William Hunsicker
May 23 '13, 7:18 a.m.Millard. That is correct. Sorry for not providing the versions before. The brain wasnt quite working on all cylinders. Eclipse version 3.6.2 and RTC Client version 4.0. This also occurs in RTC Client verion 4.0.1 running in Eclipse version 3.6.3. Server is RTC version 4.0.1
Millard Ellingsworth
FORUM ADMINISTRATOR / JAZZ DEVELOPER May 23 '13, 2:55 p.m.Sorry, I had another question in there: After this happens, does your Eclipse client remain in error or will a restart/refresh type action make things work again?
William Hunsicker
May 23 '13, 2:59 p.m.Sorry about that. Too many things going on at one time. :)
The error occurs each and every time I go into Eclipse and attempt to access the timesheet tab of the work item. Restarting has no affect on the behavior. The other tabs all seem to work fine both before and after I attempt to access the timesheet tab.
Ralph Schoon
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER Jun 18 '13, 11:47 a.m.Not sure if this could cause issues, but you never disconnect your WorkingCopyManager from the workitem as described here http://rsjazz.wordpress.com/2013/03/20/understanding-and-using-the-rtc-java-client-api/ (search for disconnect). I am not sure of the effects this could have. I usually use WorkitemOperations instead of using the WorkingCopyManager as described here: https://rsjazz.wordpress.com/2012/11/26/manipulating-work-item-states/
William Hunsicker
May 24 '13, 11:18 a.m.Thanks Ralph. I had placed the disconnect into the code and saw no difference. I will take a look at the WorkItemOperations and see if that can help out.
Ralph Schoon
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER May 24 '13, 11:24 a.m.William, please provide your solution, as I think others would be interested to see this too. I know that other customers have done automation and even their own UIs for this data, so I assume it can be done. It would be interesting to understand what causes the error - if it is not a defect.
Ralph Schoon
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER May 24 '13, 11:31 a.m.Another thought..... I have seen issues like that in case the links were not created correctly. You might check https://rsjazz.wordpress.com/2012/09/19/the-rtc-workitem-link-api-linking-workitems-to-other-elements/ for how links are created. I think my code looks different than yours. I have no idea if that could cause it however.
William Hunsicker
Jun 04 '13, 9:01 a.m.Hi Ralph, Sorry this took so long to reply. I looked at your link, and the basic functionality for your code is here:
IItemReference reference = IReferenceFactory.INSTANCE.createReferenceToItem(fOpposite);
workingCopy.getReferences().add(WorkItemEndPoints.BLOCKS_WORK_ITEM, reference);
In my code, I use the same calls here:
IItemReference tsRef = IReferenceFactory.INSTANCE.createReferenceToItem(newEntry); //Note newEntry is a pointer to the new TimeSheet object.
IWorkItemReferences itemReference = wc.getReferences();
itemReference.add(WorkItemEndPoints.WORK_TIME, tsRef);
not quite sure why the timesheet reference is different than the one you provided as an example.
William Hunsicker
Jun 10 '13, 7:54 a.m.Millard, I finally got back to being able to test this more. Cleared the log and went in to create the error again to validate what I was seeing before. Am able to recreate the error, but now get this stack trace.
Millard Ellingsworth
FORUM ADMINISTRATOR / JAZZ DEVELOPER Jun 11 '13, 12:36 p.m.I've emailed a link to this question to the tracking and planning team and asked them to please lend a hand. Hopefully that will get you some more help.
William Hunsicker
Jun 18 '13, 9:36 a.m.Hi Millard, Just checking to see if there is any word on the possible tracking and planning team help.
Millard Ellingsworth
FORUM ADMINISTRATOR / JAZZ DEVELOPER Jun 18 '13, 11:46 a.m.I sent an email to the TAP distribution list last week, apparently there were no takers, sorry. I'd suggest looking at Ralph's example more carefully, perhaps seeing if his will work in your environment. Maybe that will trigger some thoughts on what is missing.