88package com .powsybl .ucte .converter ;
99
1010import com .google .auto .service .AutoService ;
11- import com .google .common .base .Suppliers ;
1211import com .powsybl .commons .PowsyblException ;
1312import com .powsybl .commons .config .PlatformConfig ;
1413import com .powsybl .commons .datasource .DataSource ;
1514import com .powsybl .commons .parameters .ConfiguredParameter ;
1615import com .powsybl .commons .parameters .Parameter ;
1716import com .powsybl .commons .parameters .ParameterDefaultValueConfig ;
1817import com .powsybl .commons .parameters .ParameterType ;
19- import com .powsybl .commons .util .ServiceLoaderCache ;
2018import com .powsybl .iidm .network .*;
2119import com .powsybl .iidm .network .extensions .SlackTerminal ;
2220import com .powsybl .ucte .converter .util .UcteConverterHelper ;
3028import java .nio .charset .StandardCharsets ;
3129import java .time .ZonedDateTime ;
3230import java .util .*;
33- import java .util .function .Supplier ;
3431
3532import static com .powsybl .ucte .converter .util .UcteConverterConstants .*;
3633import static com .powsybl .ucte .converter .util .UcteConverterHelper .*;
@@ -56,9 +53,6 @@ public class UcteExporter implements Exporter {
5653
5754 private static final List <Parameter > STATIC_PARAMETERS = List .of (NAMING_STRATEGY_PARAMETER , COMBINE_PHASE_ANGLE_REGULATION_PARAMETER );
5855
59- private static final Supplier <List <NamingStrategy >> NAMING_STRATEGY_SUPPLIERS
60- = Suppliers .memoize (() -> new ServiceLoaderCache <>(NamingStrategy .class ).getServices ());
61-
6256 private final ParameterDefaultValueConfig defaultValueConfig ;
6357
6458 public UcteExporter () {
@@ -86,7 +80,14 @@ public void export(Network network, Properties parameters, DataSource dataSource
8680 }
8781
8882 String namingStrategyName = Parameter .readString (getFormat (), parameters , NAMING_STRATEGY_PARAMETER , defaultValueConfig );
89- NamingStrategy namingStrategy = findNamingStrategy (namingStrategyName , NAMING_STRATEGY_SUPPLIERS .get ());
83+ // a new instance is requested from the ServiceLoader for each export, instead of caching and
84+ // reusing one across exports, so that concurrent exports don't share (and corrupt) the same
85+ // NamingStrategy's internal id-mapping state
86+ List <NamingStrategy > namingStrategies = ServiceLoader .load (NamingStrategy .class , UcteExporter .class .getClassLoader ())
87+ .stream ()
88+ .map (ServiceLoader .Provider ::get )
89+ .toList ();
90+ NamingStrategy namingStrategy = findNamingStrategy (namingStrategyName , namingStrategies );
9091 namingStrategy .initializeNetwork (network );
9192 boolean combinePhaseAngleRegulation = Parameter .readBoolean (getFormat (), parameters , COMBINE_PHASE_ANGLE_REGULATION_PARAMETER , defaultValueConfig );
9293
@@ -824,8 +825,8 @@ static NamingStrategy findNamingStrategy(String name, List<NamingStrategy> namin
824825
825826 if (namingStrategies .size () == 1 && name == null ) {
826827 // no information to select the implementation but only one naming strategy, so we can use it by default
827- // (that is be the most common use case)
828- return namingStrategies .get ( 0 );
828+ // (that is the most common use case)
829+ return namingStrategies .getFirst ( );
829830 } else {
830831 if (namingStrategies .size () > 1 && name == null ) {
831832 // several naming strategies and no information to select which one to choose, we can only throw
0 commit comments