It's all about the answers!

Ask a question

Saving Timesheet Entry causes Error in Eclipse IDE but not web UI


William Hunsicker (4059) | asked May 22 '13, 1:40 p.m.
 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/variables
if (!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 everything
Iterator<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 back
IWorkItem wiCopy = wc.getWorkItem();
IWorkItemHandle copyHandle = (IWorkItemHandle) wiCopy.getItemHandle();
// Move the new duration into the DB
wiCopy.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 them
Iterator<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 found
found = 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 new
ITimeSheetEntry 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 commented May 22 '13, 6:46 p.m.
FORUM ADMINISTRATOR / JAZZ DEVELOPER

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 commented 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 commented May 23 '13, 2:55 p.m.
FORUM ADMINISTRATOR / JAZZ DEVELOPER

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 commented 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 commented May 24 '13, 7:47 a.m. | edited Jun 18 '13, 11:47 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

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 commented 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 commented May 24 '13, 11:24 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

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 commented May 24 '13, 11:30 a.m. | edited May 24 '13, 11:31 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

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 commented 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 commented 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.


java.lang.NullPointerException
at com.ibm.team.tpt.ide.ui.timesheet.internal.helper.TimeSheetTableHelper.createTimesheetRow(TimeSheetTableHelper.java:140)
at com.ibm.team.tpt.ide.ui.timesheet.internal.helper.TimeSheetTableHelper.refresh(TimeSheetTableHelper.java:93)
at com.ibm.team.tpt.ide.ui.timesheet.internal.helper.TimeSheetTableHelper.setWeekDate(TimeSheetTableHelper.java:67)

Is there any way you can let me know what the code is trying to do there that is getting the null pointer so I can modify my code to ensure that is not null?


Millard Ellingsworth commented Jun 11 '13, 12:36 p.m.
FORUM ADMINISTRATOR / JAZZ DEVELOPER

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 commented 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.


Thanks,

Bill


Millard Ellingsworth commented Jun 18 '13, 11:46 a.m.
FORUM ADMINISTRATOR / JAZZ DEVELOPER

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.


I'll change Ralph's answer to a comment -- perhaps someone else from the community who has worked successfully with this data can lend a hand.

showing 5 of 13 show 8 more comments

Accepted answer


permanent link
William Hunsicker (4059) | answered Jul 03 '13, 7:28 a.m.
 Ok, I managed to figure out what the problem was.  As it turns out I was saving the incorrect value for the .setTimeCodeId() method.  I was using "Default" when I needed to use "timecode.literal.l1"

Thanks to everyone who helped with ideas and advice.

Bill Hunsicker
Ralph Schoon selected this answer as the correct answer

Comments
Ralph Schoon commented Jul 03 '13, 7:38 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Thanks for providing this information.

Your answer


Register or to post your answer.