2626import java .util .Map ;
2727import java .util .Properties ;
2828import java .util .Vector ;
29+ import java .util .concurrent .CountDownLatch ;
2930
3031import org .apache .maven .plugin .AbstractMojo ;
3132import org .apache .maven .plugin .MojoExecutionException ;
@@ -79,47 +80,26 @@ public void execute() throws MojoExecutionException {
7980 ClassLoader pluginRealm = getClass ().getClassLoader ();
8081 ClassLoader coreRealm = MojoExecutionException .class .getClassLoader ();
8182
82- final Map map = componentMap ;
83- final List list = componentList ;
84- final List go = new Vector ();
85- final List exceptions = new Vector ( );
83+ final Map < String , TestComponent > map = componentMap ;
84+ final List < TestComponent > list = componentList ;
85+ final List < Exception > exceptions = new Vector <> ();
86+ final CountDownLatch startLatch = new CountDownLatch ( 1 );
8687
8788 Thread [] threads = new Thread [2 ];
8889 for (int i = 0 ; i < threads .length ; i ++) {
8990 // NOTE: The threads need to use different realms to trigger changes of the collections
9091 final ClassLoader cl = (i % 2 ) == 0 ? pluginRealm : coreRealm ;
91- threads [i ] = new Thread () {
92- private final ClassLoader tccl = cl ;
93-
94- public void run () {
95- getLog ().info ("[MAVEN-CORE-IT-LOG] Thread " + this + " uses " + tccl );
96- Thread .currentThread ().setContextClassLoader (tccl );
97- while (go .isEmpty ()) {
98- // wait for start
99- }
100- for (int j = 0 ; j < 10 * 1000 ; j ++) {
101- try {
102- for (Object o : map .values ()) {
103- o .toString ();
104- }
105- for (Object aList : list ) {
106- aList .toString ();
107- }
108- } catch (Exception e ) {
109- getLog ().warn ("[MAVEN-CORE-IT-LOG] Thread " + this + " encountered concurrency issue" , e );
110- exceptions .add (e );
111- }
112- }
113- }
114- };
92+ threads [i ] = new CheckThreadSafetyThread (cl , startLatch , map , list , exceptions );
11593 threads [i ].start ();
11694 }
11795
118- go .add (null );
96+ startLatch .countDown (); // Signal all threads to start
97+
11998 for (Thread thread : threads ) {
12099 try {
121100 thread .join ();
122101 } catch (InterruptedException e ) {
102+ Thread .currentThread ().interrupt ();
123103 getLog ().warn ("[MAVEN-CORE-IT-LOG] Interrupted while joining " + thread );
124104 }
125105 }
@@ -133,23 +113,60 @@ public void run() {
133113
134114 getLog ().info ("[MAVEN-CORE-IT-LOG] Creating output file " + outputFile );
135115
136- OutputStream out = null ;
137- try {
116+ try (OutputStream out = new FileOutputStream (outputFile )) {
138117 outputFile .getParentFile ().mkdirs ();
139- out = new FileOutputStream (outputFile );
140118 componentProperties .store (out , "MAVEN-CORE-IT-LOG" );
141119 } catch (IOException e ) {
142120 throw new MojoExecutionException ("Output file could not be created: " + outputFile , e );
143- } finally {
144- if (out != null ) {
121+ }
122+
123+ getLog ().info ("[MAVEN-CORE-IT-LOG] Created output file " + outputFile );
124+ }
125+
126+ class CheckThreadSafetyThread extends Thread {
127+ private final ClassLoader tccl ;
128+ private final CountDownLatch startLatch ;
129+ private final Map <String , TestComponent > map ;
130+ private final List <TestComponent > list ;
131+ private final List <Exception > exceptions ;
132+
133+ CheckThreadSafetyThread (ClassLoader cl , CountDownLatch startLatch ,
134+ Map <String , TestComponent > map , List <TestComponent > list ,
135+ List <Exception > exceptions ) {
136+ this .tccl = cl ;
137+ this .startLatch = startLatch ;
138+ this .map = map ;
139+ this .list = list ;
140+ this .exceptions = exceptions ;
141+ }
142+
143+ @ Override
144+ public void run () {
145+ getLog ().info ("[MAVEN-CORE-IT-LOG] Thread " + this + " uses " + tccl );
146+ Thread .currentThread ().setContextClassLoader (tccl );
147+ try {
148+ startLatch .await (); // Wait for the start signal
149+ checkThreadSafety ();
150+ } catch (InterruptedException e ) {
151+ Thread .currentThread ().interrupt ();
152+ getLog ().warn ("[MAVEN-CORE-IT-LOG] Thread " + this + " was interrupted while waiting" );
153+ }
154+ }
155+
156+ private void checkThreadSafety () {
157+ for (int j = 0 ; j < 10 * 1000 ; j ++) {
145158 try {
146- out .close ();
147- } catch (IOException e ) {
148- // just ignore
159+ for (Object o : map .values ()) {
160+ o .toString ();
161+ }
162+ for (Object aList : list ) {
163+ aList .toString ();
164+ }
165+ } catch (Exception e ) {
166+ getLog ().warn ("[MAVEN-CORE-IT-LOG] Thread " + this + " encountered concurrency issue" , e );
167+ exceptions .add (e );
149168 }
150169 }
151170 }
152-
153- getLog ().info ("[MAVEN-CORE-IT-LOG] Created output file " + outputFile );
154171 }
155- }
172+ }
0 commit comments