I’ve been trying to implement a custom routing profile that will choose primary roads over secondary. So far I have the following code:
GraphHopper graphHopper() {
final var graphHopperConfiguration = new GraphHopperConfig();
graphHopperConfiguration.putObject("datareader.file", "my-path-to-file");
graphHopperConfiguration.putObject("graph.location", "my-path-to-graph-cache");
graphHopperConfiguration.putObject("graph.flag_encoders", "car|turn_costs=true");
graphHopperConfiguration.setProfiles(List.of(getProfile()));
return new GraphHopper().init(graphHopperConfiguration).importOrLoad();
}
private Profile getProfile() {
final var customModel = new CustomModel();
customModel.addToPriority(If("road_class == SECONDARY", MULTIPLY, 0.3));
customModel.setDistanceInfluence(150);
return new CustomProfile("car_profile")
.setCustomModel(customModel)
.setVehicle("car")
.setTurnCosts(true);
}
However, when I run my code the following exception is thrown:
Error: Cannot compile expression: Enclosing scope is already set for statement "protected EnumEncodedValue road_class_enc" at File 'source', Line 8, Column 11
After hours of debugging and investigations, I can confirm that the issue lies in CustomModelParser.injectStatements.copyFieldDeclaration().
It seems like the DeepCopier tries to reassign road_class_enc variable that was already declared in the classTemplate string (line 129).
Did anyone encounter this issue? Any help would be very much appreciated
You can you have a look into RoutingExample and RouteResourceCustomModelTest (for your version e.g. 5.x) to see how you can make this working. Would be still interesting why this fails for you and how we can improve the error message in this case.
I would like to mention that when I use non-custom profiles or if I don’t addToPriority then everything works fine and no exception is thrown. I’ll have a look at RouteResourceCustomModelTest and come back with additional feedback. Cheers
I did investigate further this issue and found out that Java.Statement.setEnclosingScope from janino module is indeed called twice with the same value: JaninoCustomWeightingHelperSubclass2
The first time it is called immediately after executing fd.setEnclosingScope (line 350 in CustomModelParser) and the second time it’s probably executed internally by janino library (although I’m not sure) which causes this exception to be thrown.
There is no such issue in the release (otherwise many tests would fail). You can of course provide us with a reproducer unit test that fails with this exception and I’ll have a look.
(btw: please make sure that you disable JANINO_DEBUG and remove all generated Java classes from the project before you compile it)