Exception: ArgumentOutOfRangeException on exporting MPP (Java)

Hi,

We have a schedule with almost 2000 activities and we are unable to export to project.

It is very slow in resource assignments.

After 4 hours of execution the following error happens:

Exception in thread "main" class com.aspose.tasks.private_.Exceptions.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: Parameter name: index
com.aspose.tasks.private_.Collections.Generic.List.b(Unknown Source)
com.aspose.tasks.SplitPartCollection.a(Unknown Source)
com.aspose.tasks.dfg.h(Unknown Source)
com.aspose.tasks.bdk.b(Unknown Source)
com.aspose.tasks.xw.a(Unknown Source)
com.aspose.tasks.gm.a(Unknown Source)
com.aspose.tasks.gm.a(Unknown Source)
com.aspose.tasks.ResourceAssignment.a(Unknown Source)
com.aspose.tasks.ResourceAssignment.set(Unknown Source)

Below is the sample source code and csv file with the activities:

public class TestExportProject {

	private static final DateFormat DF = new SimpleDateFormat("dd/MM/yyyy");

	public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
		long startTime = System.nanoTime();
		List<List<String>> records = new ArrayList<>();
		try (BufferedReader br = new BufferedReader(
				new FileReader(TestExportProject.class.getResource("tasks.csv").getFile()))) {
			String line;
			while ((line = br.readLine()) != null) {
				String[] values = line.split(";");
				records.add(Arrays.asList(values));
			}
		}
		records.remove(0);

		AsposeTasksLicenseLoader.loadLicense();
		Project project = new Project();
		project.set(Prj.START_DATE, DF.parse(records.get(0).get(3)));
		project.setCalculationMode(CalculationMode.None);
		List<Task> tasks = new ArrayList<Task>();
		Task rootTask = project.getRootTask();
		for (List<String> csvTask : records) {
			Task task = rootTask.getChildren().add(csvTask.get(1));
			if (!csvTask.get(2).isEmpty()) {
				task.set(Tsk.DURATION, project.getDuration(
						Double.parseDouble(csvTask.get(2).replace(".", "").replace(",", ".")), TimeUnitType.Minute));
			}
			if (!csvTask.get(3).isEmpty()) {
				Date start = DF.parse(csvTask.get(3));
				task.set(Tsk.START, start);
				task.set(Tsk.CONSTRAINT_TYPE, ConstraintType.StartNoEarlierThan);
				task.set(Tsk.CONSTRAINT_DATE, start);
			}
			if (!csvTask.get(4).isEmpty()) {
				task.set(Tsk.FINISH, DF.parse(csvTask.get(4)));
			}
			tasks.add(task);
		}
		project.setCalculationMode(CalculationMode.Automatic);
		project.recalculate();
		
		ChildTasksCollector collector = new ChildTasksCollector();
		TaskUtils.apply(project.getRootTask(), collector, 0);
		List<Task> tasksView = collector.getTasks();
		for (Task task : tasksView) {
			printTask(task);
		}
		
		long endTaskTime = System.nanoTime();
		
		long timeTaskElapsed = endTaskTime - startTime;
		System.out.println("Execution time to export tasks in milliseconds : " + 
				timeTaskElapsed / 1000000);
		
		long startResourcesTime = System.nanoTime();
		Map<String, Resource> mapResources = new HashMap<String, Resource>();
		for (int i = 0; i < records.size(); i++) {
			List<String> csvTask = records.get(i);
			
			if (csvTask.size() < 6 || csvTask.get(5).isEmpty()) {
				continue;
			}
			String[] taskResources = csvTask.get(5).split(",");
			for (String csvResource : taskResources) {
				Resource resource = mapResources.get(csvResource);
				if (resource == null) {
					resource = project.getResources().add(csvResource);
					mapResources.put(csvResource, resource);
				}
				project.getResourceAssignments().add(tasks.get(i), resource).set(Asn.UNITS, 100d);
			}
		}

		collector = new ChildTasksCollector();
		TaskUtils.apply(project.getRootTask(), collector, 0);
		tasksView = collector.getTasks();
		for (Task task : tasksView) {
			printTask(task);
		}
		
		long endResourcesTime = System.nanoTime();
		
		long timeResourcesElapsed = endResourcesTime - startResourcesTime;
		System.out.println("Execution time to export resources in milliseconds : " + 
				timeResourcesElapsed / 1000000);
	
		long timeTotalElapsed = endResourcesTime - startTime;
		System.out.println("Execution  total time to export in milliseconds : " + 
				timeTotalElapsed / 1000000);
	}

	private static void printTask(Task task) {
		System.out.println(task.get(Tsk.ID) + " | " + task.get(Tsk.NAME) + " | " + task.get(Tsk.START) + " | "
				+ task.get(Tsk.FINISH) + " | " + task.get(Tsk.DURATION));
	}
}

tasks.csv.zip (8.1 KB)

Using Aspose Tasks for Java.

@jexperts,

I have observed your requirements and regret to share that at present the requested support of loading CSV and save as MPP is unavailable in API. An issue with ID TASKSJAVA-985 has been created in our issue tracking system to further investigate and resolve the issue. This thread has been linked with the issue so that you may be notified once the issue will be fixed.

As far as your file is concerned, you are parsing your own CSV format, so we cannot implement CSV parser for this case as it is beyond scope of API. As far as question of why the adding of assignment is so slow, we have noticed that you set CalculationMode to None ( project.setCalculationMode(CalculationMode.None) ;

before the beginning of the reading the project - that is correct.But you set CalculationMode to Automatic before creating the assignments and thus creating of assignment takes so much time. You could try to move these lines:

project.setCalculationMode(CalculationMode.None);	
project.recalculate() 

to the end of the code block that creates assignment, just before this line:

collector = new ChildTasksCollector();
TaskUtils.apply(project.getRootTask(), collector, 0);
tasksView = collector.getTasks();

Hi,

We try to set project.setCalculationMode(CalculationMode.None) before and after creates assignment and others things but it made no difference in processing speed.

About CSV, it’s only an example to load the tasks and we don’t use in production.

@jexperts,

We suggested you to use following instead of CalculationMode.None. Please try using suggested options as shared by me in my last post on your end which include following.

@mudassir.fayyaz,

We try you suggestion, but did not work.

This issue is greatly harming our customers.

@jexperts,

Can you please try using latest Aspose.Tasks for Java 19.7 on your end as we have tested your code and CSV in Windows 10 with JDK 1.8 and it took 7 seconds. Which is fair value. Can you please share what statistics you are having on your end along with Java and Operating System details.

Hi,

Any news about this issue?

Many of our customers are being affected.

We tested again with latest aspose tasks for java 19.10 and the same issue happen.

Java version: jdk 7 update 80 and jdk 8 update 211.

Operational System: Linux Mint 19.2 Cinnamon
Linux kernel: 4.15.0-66-generic
Processor: Intel© Core™ i7-8565U CPU @ 1.80GHz × 4
RAM memory: 16GB

@jexperts,

I regret to inform that issue is still unresolved. We are working on this and will share news regarding ETA soon. I request for your patience.

@jexperts,

I like to inform that we have investigated this issue on our end. Can you please turn off automatic calculation by project.setCalculationMode(CalculationMode.None) and do project.recalculate() one time before tasks output. You should consider to remove the printing of tasks between readings because of need of extra recalculation in that case. When we turned off Automatic recalculation of project, we measured 1 second for tasks processing and 27 seconds for resources with about 7000 assignments, which is acceptable. The most time-consuming thing is project.recalculate(). We cannot optimize this because of very complex logic’s of project’s recalculation.