Skip to content

Commit 1c6c205

Browse files
committed
Fix for Data deadlock with EJB in .war
1 parent b633e42 commit 1c6c205

File tree

3 files changed

+32
-36
lines changed

3 files changed

+32
-36
lines changed

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/DataProvider.java

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ public void componentMetaDataCreated(MetaDataEvent<ComponentMetaData> event) {
410410

411411
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
412412
Tr.debug(this, tc, "componentMetaDataCreated " + jeeName, metadata);
413+
413414
}
414415

415416
@Override
@@ -880,9 +881,7 @@ public void moduleStarted(ModuleInfo moduleInfo) throws StateChangeException {
880881
public void moduleStarting(ModuleInfo moduleInfo) throws StateChangeException {
881882
final boolean trace = TraceComponent.isAnyTracingEnabled();
882883

883-
// TODO here and elsewhere: use whichever of getDeploymentName() or getName()
884-
// is guaranteed to match J2EEName
885-
String appName = moduleInfo.getApplicationInfo().getName();
884+
String appName = moduleInfo.getApplicationInfo().getDeploymentName();
886885
String moduleName = moduleInfo.getName(); // does not include .jar at the end
887886

888887
if (trace && tc.isDebugEnabled())
@@ -896,33 +895,21 @@ public void moduleStarting(ModuleInfo moduleInfo) throws StateChangeException {
896895
Set<FutureEMBuilder> futures = futureEMBuilders.get(appName);
897896
if (futures != null)
898897
for (FutureEMBuilder futureEMBuilder : futures) {
899-
// The JEE name includes .jar at the end of EJB modules
900-
String moduleNameWithDot = futureEMBuilder.jeeName.getModule();
901-
902-
if (!futureEMBuilder.inWebModule &&
903-
moduleNameWithDot != null &&
904-
moduleNameWithDot.length() == moduleName.length() + 4 &&
905-
moduleNameWithDot.startsWith(moduleName) &&
906-
moduleNameWithDot.endsWith(".jar")) {
907-
908-
if (trace && tc.isDebugEnabled())
909-
Tr.debug(this, tc, "matched with " + futureEMBuilder.jeeName);
910-
911-
// This delays createEMBuilder until restore.
912-
// While this works by avoiding all connections to the data source, it does make restore much slower.
913-
// TODO figure out how to do more work on restore without having to make a connection to the data source
914-
CheckpointPhase.onRestore(() -> futureEMBuilder.completeAsync(futureEMBuilder::createEMBuilder, executor));
898+
// This delays createEMBuilder until restore.
899+
// While this works by avoiding all connections to the data source, it does make restore much slower.
900+
// TODO figure out how to do more work on restore without having to make a connection to the data source
901+
CheckpointPhase.onRestore(() -> futureEMBuilder.completeAsync(futureEMBuilder::createEMBuilder, executor));
902+
903+
if (processed == null) {
904+
processed = new ConcurrentSkipListSet<>();
905+
Set<FutureEMBuilder> previous = futureEMBuildersInEJB //
906+
.putIfAbsent(appName, processed);
907+
if (previous != null)
908+
processed = previous;
909+
}
915910

916-
if (processed == null) {
917-
processed = new ConcurrentSkipListSet<>();
918-
Set<FutureEMBuilder> previous = futureEMBuildersInEJB //
919-
.putIfAbsent(appName, processed);
920-
if (previous != null)
921-
processed = previous;
922-
}
911+
processed.add(futureEMBuilder);
923912

924-
processed.add(futureEMBuilder);
925-
}
926913
}
927914
}
928915

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/cdi/FutureEMBuilder.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ public EntityManagerBuilder createEMBuilder() {
296296
final boolean trace = TraceComponent.isAnyTracingEnabled();
297297
try {
298298
String resourceName = dataStore;
299-
String metadataIdentifier = getMetadataIdentifier();
299+
String metadataIdentifier = getMetadataIdentifier(inWebModule);
300300

301301
// metadataIdentifier examples:
302302
// WEB#MyApp#MyWebModule.war
@@ -335,8 +335,13 @@ public EntityManagerBuilder createEMBuilder() {
335335
metadata = (ComponentMetaData) provider.metadataIdSvc //
336336
.getMetaData(metadataIdentifier);
337337
} catch (IllegalStateException x) {
338-
if (System.nanoTime() - start > TimeUnit.SECONDS.toNanos(30))
339-
throw x;
338+
try { //Check if this is an EJB in a Web Module
339+
metadata = (ComponentMetaData) provider.metadataIdSvc //
340+
.getMetaData(getMetadataIdentifier(false));
341+
} catch (IllegalStateException y) {
342+
if (System.nanoTime() - start > TimeUnit.SECONDS.toNanos(30))
343+
throw x; //Throw exception for non-EJB check
344+
}
340345
// else retry because the deferred metadata is not available yet
341346
}
342347
} while (metadata == null);
@@ -672,11 +677,14 @@ private J2EEName getArtifactName(Class<?> repositoryInterface,
672677
* Obtains the metadata identifier for the module that defines the repository
673678
* interface.
674679
*
680+
* @param webModule true for a Web Module, false for an EJB Module
681+
*
675682
* @return metadata identifier as the key, and application/module/component
676683
* as the value. Module and component might be null or might not be
677684
* present at all.
678685
*/
679-
private String getMetadataIdentifier() {
686+
private String getMetadataIdentifier(boolean webModule) {
687+
680688
String mdIdentifier;
681689

682690
if (jeeName.getModule() == null) {
@@ -685,7 +693,7 @@ private String getMetadataIdentifier() {
685693
null);
686694
} else {
687695
mdIdentifier = provider.metadataIdSvc //
688-
.getMetaDataIdentifier(inWebModule ? "WEB" : "EJB",
696+
.getMetaDataIdentifier(webModule ? "WEB" : "EJB",
689697
jeeName.getApplication(),
690698
jeeName.getModule(),
691699
null);

dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestEJB.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import jakarta.annotation.PostConstruct;
1616
import jakarta.ejb.Singleton;
1717
import jakarta.ejb.Startup;
18+
import jakarta.inject.Inject;
1819

1920
/**
2021
* A singleton startup EJB that is included inside the war file.
@@ -24,11 +25,11 @@
2425
public class DataTestEJB {
2526

2627
//TODO renable after fixing deadlock in DataProvider
27-
// @Inject
28-
// Animals animals;
28+
@Inject
29+
Animals animals;
2930

3031
@PostConstruct
3132
public void init() {
32-
// animals.findAll();
33+
animals.findAll();
3334
}
3435
}

0 commit comments

Comments
 (0)