29
29
import java .util .Properties ;
30
30
import java .util .Set ;
31
31
import java .util .TreeSet ;
32
+ import java .util .concurrent .CompletableFuture ;
33
+ import java .util .concurrent .ConcurrentLinkedDeque ;
34
+ import java .util .concurrent .ExecutionException ;
35
+ import java .util .concurrent .ExecutorService ;
36
+ import java .util .concurrent .Future ;
32
37
import java .util .function .BiConsumer ;
33
38
import java .util .stream .Collectors ;
34
39
@@ -465,7 +470,8 @@ public BytecodeRecorderConstantDefinitionBuildItem pregenProxies(
465
470
List <PersistenceUnitDescriptorBuildItem > persistenceUnitDescriptorBuildItems ,
466
471
List <AdditionalJpaModelBuildItem > additionalJpaModelBuildItems ,
467
472
BuildProducer <GeneratedClassBuildItem > generatedClassBuildItemBuildProducer ,
468
- LiveReloadBuildItem liveReloadBuildItem ) {
473
+ LiveReloadBuildItem liveReloadBuildItem ,
474
+ ExecutorService buildExecutor ) throws ExecutionException , InterruptedException {
469
475
Set <String > managedClassAndPackageNames = new HashSet <>(jpaModel .getEntityClassNames ());
470
476
for (PersistenceUnitDescriptorBuildItem pud : persistenceUnitDescriptorBuildItems ) {
471
477
// Note: getManagedClassNames() can also return *package* names
@@ -479,9 +485,9 @@ public BytecodeRecorderConstantDefinitionBuildItem pregenProxies(
479
485
managedClassAndPackageNames .add (additionalJpaModelBuildItem .getClassName ());
480
486
}
481
487
482
- PreGeneratedProxies proxyDefinitions = generatedProxies (managedClassAndPackageNames ,
488
+ PreGeneratedProxies proxyDefinitions = generateProxies (managedClassAndPackageNames ,
483
489
indexBuildItem .getIndex (), transformedClassesBuildItem ,
484
- generatedClassBuildItemBuildProducer , liveReloadBuildItem );
490
+ generatedClassBuildItemBuildProducer , liveReloadBuildItem , buildExecutor );
485
491
486
492
// Make proxies available through a constant;
487
493
// this is a hack to avoid introducing circular dependencies between build steps.
@@ -1372,53 +1378,65 @@ private static MultiTenancyStrategy getMultiTenancyStrategy(Optional<String> mul
1372
1378
return multiTenancyStrategy ;
1373
1379
}
1374
1380
1375
- private PreGeneratedProxies generatedProxies (Set <String > managedClassAndPackageNames , IndexView combinedIndex ,
1381
+ private PreGeneratedProxies generateProxies (Set <String > managedClassAndPackageNames , IndexView combinedIndex ,
1376
1382
TransformedClassesBuildItem transformedClassesBuildItem ,
1377
1383
BuildProducer <GeneratedClassBuildItem > generatedClassBuildItemBuildProducer ,
1378
- LiveReloadBuildItem liveReloadBuildItem ) {
1384
+ LiveReloadBuildItem liveReloadBuildItem ,
1385
+ ExecutorService buildExecutor ) throws ExecutionException , InterruptedException {
1379
1386
ProxyCache proxyCache = liveReloadBuildItem .getContextObject (ProxyCache .class );
1380
1387
if (proxyCache == null ) {
1381
1388
proxyCache = new ProxyCache ();
1382
1389
liveReloadBuildItem .setContextObject (ProxyCache .class , proxyCache );
1383
1390
}
1384
- Set <String > changedClasses = Collections . emptySet ();
1391
+ Set <String > changedClasses = Set . of ();
1385
1392
if (liveReloadBuildItem .getChangeInformation () != null ) {
1386
1393
changedClasses = liveReloadBuildItem .getChangeInformation ().getChangedClasses ();
1387
1394
} else {
1388
1395
//we don't have class change info, invalidate the cache
1389
1396
proxyCache .cache .clear ();
1390
1397
}
1391
1398
//create a map of entity to proxy type
1392
- PreGeneratedProxies preGeneratedProxies = new PreGeneratedProxies ();
1393
1399
TypePool transformedClassesTypePool = createTransformedClassesTypePool (transformedClassesBuildItem ,
1394
1400
managedClassAndPackageNames );
1401
+
1402
+ PreGeneratedProxies preGeneratedProxies = new PreGeneratedProxies ();
1403
+
1395
1404
try (ProxyBuildingHelper proxyHelper = new ProxyBuildingHelper (transformedClassesTypePool )) {
1405
+ final ConcurrentLinkedDeque <Future <CachedProxy >> generatedProxyQueue = new ConcurrentLinkedDeque <>();
1406
+ Set <String > proxyInterfaceNames = Set .of (ClassNames .HIBERNATE_PROXY .toString ());
1407
+
1396
1408
for (String managedClassOrPackageName : managedClassAndPackageNames ) {
1397
- CachedProxy result ;
1398
1409
if (proxyCache .cache .containsKey (managedClassOrPackageName )
1399
1410
&& !isModified (managedClassOrPackageName , changedClasses , combinedIndex )) {
1400
- result = proxyCache .cache .get (managedClassOrPackageName );
1411
+ CachedProxy proxy = proxyCache .cache .get (managedClassOrPackageName );
1412
+ generatedProxyQueue .add (CompletableFuture .completedFuture (proxy ));
1401
1413
} else {
1402
- Set <String > proxyInterfaceNames = new TreeSet <>();
1403
- proxyInterfaceNames .add (ClassNames .HIBERNATE_PROXY .toString ()); //always added
1404
1414
if (!proxyHelper .isProxiable (combinedIndex .getClassByName (managedClassOrPackageName ))) {
1405
1415
// we need to make sure the actual class is proxiable
1406
1416
continue ;
1407
1417
}
1408
- final String mappedClass = managedClassOrPackageName ;
1409
- DynamicType .Unloaded <?> unloaded = proxyHelper .buildUnloadedProxy (mappedClass , proxyInterfaceNames );
1410
- result = new CachedProxy (unloaded , proxyInterfaceNames );
1411
- proxyCache .cache .put (managedClassOrPackageName , result );
1418
+ // we now are sure we have a proper class and not a package
1419
+ String managedClass = managedClassOrPackageName ;
1420
+ generatedProxyQueue .add (buildExecutor .submit (() -> {
1421
+ DynamicType .Unloaded <?> unloaded = proxyHelper .buildUnloadedProxy (managedClass ,
1422
+ proxyInterfaceNames );
1423
+ return new CachedProxy (managedClass , unloaded , proxyInterfaceNames );
1424
+ }));
1412
1425
}
1413
- for (Entry <TypeDescription , byte []> i : result .proxyDef .getAllTypes ().entrySet ()) {
1426
+ }
1427
+
1428
+ for (Future <CachedProxy > proxyFuture : generatedProxyQueue ) {
1429
+ CachedProxy proxy = proxyFuture .get ();
1430
+ proxyCache .cache .putIfAbsent (proxy .managedClassName , proxy );
1431
+ for (Entry <TypeDescription , byte []> i : proxy .proxyDef .getAllTypes ().entrySet ()) {
1414
1432
generatedClassBuildItemBuildProducer
1415
1433
.produce (new GeneratedClassBuildItem (true , i .getKey ().getName (), i .getValue ()));
1416
1434
}
1417
- preGeneratedProxies .getProxies ().put (managedClassOrPackageName ,
1418
- new PreGeneratedProxies .ProxyClassDetailsHolder (result .proxyDef .getTypeDescription ().getName (),
1419
- result .interfaces ));
1435
+ preGeneratedProxies .getProxies ().put (proxy .managedClassName , new PreGeneratedProxies .ProxyClassDetailsHolder (
1436
+ proxy .proxyDef .getTypeDescription ().getName (), proxy .interfaces ));
1420
1437
}
1421
1438
}
1439
+
1422
1440
return preGeneratedProxies ;
1423
1441
}
1424
1442
@@ -1476,10 +1494,12 @@ private static final class ProxyCache {
1476
1494
}
1477
1495
1478
1496
static final class CachedProxy {
1497
+ final String managedClassName ;
1479
1498
final DynamicType .Unloaded <?> proxyDef ;
1480
1499
final Set <String > interfaces ;
1481
1500
1482
- CachedProxy (DynamicType .Unloaded <?> proxyDef , Set <String > interfaces ) {
1501
+ CachedProxy (String managedClassName , DynamicType .Unloaded <?> proxyDef , Set <String > interfaces ) {
1502
+ this .managedClassName = managedClassName ;
1483
1503
this .proxyDef = proxyDef ;
1484
1504
this .interfaces = interfaces ;
1485
1505
}
0 commit comments