Skip to content

Commit 868b3d7

Browse files
committed
Support requires static transitive
1 parent 1c91b4f commit 868b3d7

File tree

11 files changed

+150
-25
lines changed

11 files changed

+150
-25
lines changed

plexus-java/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@
8181
<optional>true</optional>
8282
</dependency>
8383

84+
<dependency>
85+
<groupId>org.hamcrest</groupId>
86+
<artifactId>hamcrest</artifactId>
87+
<version>2.2</version>
88+
<scope>test</scope>
89+
</dependency>
90+
<dependency>
91+
<groupId>org.hamcrest</groupId>
92+
<artifactId>hamcrest-library</artifactId>
93+
<version>2.2</version>
94+
<scope>test</scope>
95+
</dependency>
8496
<dependency>
8597
<groupId>junit</groupId>
8698
<artifactId>junit</artifactId>

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AsmModuleInfoParser.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import java.util.Arrays;
2626
import java.util.Collections;
2727
import java.util.HashSet;
28+
import java.util.LinkedHashSet;
2829
import java.util.List;
30+
import java.util.Set;
2931

3032
import org.objectweb.asm.ClassReader;
3133
import org.objectweb.asm.ClassVisitor;
@@ -60,10 +62,19 @@ public ModuleVisitor visitModule( String name, int arg1, String arg2 )
6062
@Override
6163
public void visitRequire( String module, int access, String version )
6264
{
63-
if ( ( access & Opcodes.ACC_STATIC_PHASE ) != 0 )
65+
if ( ( access & ( Opcodes.ACC_STATIC_PHASE | Opcodes.ACC_TRANSITIVE ) ) != 0 )
6466
{
65-
wrapper.builder.requires​( Collections.singleton( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ),
66-
module );
67+
Set<JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers = new LinkedHashSet<>();
68+
if ( ( access & Opcodes.ACC_STATIC_PHASE ) != 0 )
69+
{
70+
modifiers.add( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC );
71+
}
72+
if ( ( access & Opcodes.ACC_TRANSITIVE ) != 0 )
73+
{
74+
modifiers.add( JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE );
75+
}
76+
77+
wrapper.builder.requires​( modifiers, module );
6778
}
6879
else
6980
{

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import java.util.Set;
2727

2828
/**
29-
* Simple representation of a Module containing info required by this plugin.
29+
* Simple representation of a ModuleDescriptor containing info required by this plugin.
3030
* It will provide only methods matching Java 9 ModuleDescriptor, so once Java 9 is required, we can easily switch
3131
*
3232
* @author Robert Scholte
@@ -231,7 +231,7 @@ public JavaModuleDescriptor build()
231231
}
232232

233233
/**
234-
* Represents Module.Requires
234+
* Represents ModuleDescriptor.Requires
235235
*
236236
* @author Robert Scholte
237237
* @since 1.0.0
@@ -265,14 +265,14 @@ public String name()
265265
}
266266

267267
/**
268-
* Represents Module.Requires.Modifier
268+
* Represents ModuleDescriptor.Requires.Modifier
269269
*
270270
* @author Robert Scholte
271271
* @since 1.0.0
272272
*/
273273
public static enum JavaModifier
274274
{
275-
STATIC
275+
STATIC, TRANSITIVE
276276
}
277277

278278
@Override
@@ -311,7 +311,7 @@ public boolean equals( Object obj )
311311
}
312312

313313
/**
314-
* Represents Module.Requires
314+
* Represents ModuleDescriptor.Exports
315315
*
316316
* @author Robert Scholte
317317
* @since 1.0.0
@@ -380,7 +380,7 @@ public boolean equals( Object obj )
380380
}
381381

382382
/**
383-
* Represents Module.Provides
383+
* Represents ModuleDescriptor.Provides
384384
*
385385
* @author Robert Scholte
386386
* @since 1.0.0

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ public String extract( Path path )
261261
Collections.unmodifiableMap( availableNamedModules ),
262262
Collections.unmodifiableMap( availableProviders ),
263263
requiredNamedModules,
264+
true,
264265
true );
265266
}
266267

@@ -270,7 +271,8 @@ public String extract( Path path )
270271
Collections.unmodifiableMap( availableNamedModules ),
271272
Collections.unmodifiableMap( availableProviders ),
272273
requiredNamedModules,
273-
request.isIncludeStatic() );
274+
request.isIncludeStatic(),
275+
true );
274276
}
275277

276278
// in case of identical module names, first one wins
@@ -398,13 +400,19 @@ private void selectRequires( JavaModuleDescriptor module,
398400
Map<String, JavaModuleDescriptor> availableModules,
399401
Map<String, Set<String>> availableProviders,
400402
Set<String> namedModules,
401-
boolean includeStatic )
403+
boolean includeStatic,
404+
boolean includeTransitive )
402405
{
403406
for ( JavaModuleDescriptor.JavaRequires requires : module.requires() )
404407
{
408+
// includeTransitive is one level deeper compared to includeStatic
405409
if ( includeStatic || !requires.modifiers​().contains( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ) )
406410
{
407-
selectModule( requires.name(), availableModules, availableProviders, namedModules, false );
411+
selectModule( requires.name(), availableModules, availableProviders, namedModules, false, includeStatic );
412+
}
413+
else if ( includeTransitive && requires.modifiers​().contains( JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE ) )
414+
{
415+
selectModule( requires.name(), availableModules, availableProviders, namedModules, false, includeStatic );
408416
}
409417
}
410418

@@ -418,21 +426,21 @@ private void selectRequires( JavaModuleDescriptor module,
418426

419427
if ( requiredModule != null && namedModules.add( providerModule ) )
420428
{
421-
selectRequires( requiredModule, availableModules, availableProviders, namedModules, false );
429+
selectRequires( requiredModule, availableModules, availableProviders, namedModules, false, includeStatic );
422430
}
423431
}
424432
}
425433
}
426434
}
427435

428436
private void selectModule( String module, Map<String, JavaModuleDescriptor> availableModules, Map<String, Set<String>> availableProviders,
429-
Set<String> namedModules, boolean includeStatic )
437+
Set<String> namedModules, boolean includeStatic, boolean includeTransitive )
430438
{
431439
JavaModuleDescriptor requiredModule = availableModules.get( module );
432440

433441
if ( requiredModule != null && namedModules.add( module ) )
434442
{
435-
selectRequires( requiredModule, availableModules, availableProviders, namedModules, includeStatic );
443+
selectRequires( requiredModule, availableModules, availableProviders, namedModules, includeStatic, includeTransitive );
436444
}
437445
}
438446

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.nio.file.Path;
2525
import java.util.ArrayList;
2626
import java.util.Collections;
27+
import java.util.HashSet;
2728
import java.util.LinkedHashSet;
2829
import java.util.List;
2930
import java.util.Set;
@@ -56,10 +57,19 @@ public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePa
5657

5758
for ( JavaModuleDescriptor.JavaRequires requires : descriptor.getRequires() )
5859
{
59-
if ( requires.isStatic() )
60+
if ( requires.isStatic() || requires.isTransitive() )
6061
{
61-
builder.requires​( Collections.singleton( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ),
62-
requires.getModule().getName() );
62+
Set<org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers =
63+
new LinkedHashSet<>( 2 );
64+
if ( requires.isStatic() )
65+
{
66+
modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC );
67+
}
68+
if ( requires.isTransitive() )
69+
{
70+
modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE );
71+
}
72+
builder.requires​( modifiers , requires.getModule().getName() );
6373
}
6474
else
6575
{

plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
import java.lang.module.ModuleDescriptor;
2626
import java.util.Collections;
27+
import java.util.LinkedHashSet;
28+
import java.util.Set;
2729

2830
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder;
2931

@@ -38,10 +40,19 @@ JavaModuleDescriptor parse( InputStream in ) throws IOException
3840

3941
for ( ModuleDescriptor.Requires requires : descriptor.requires() )
4042
{
41-
if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.STATIC ) )
43+
if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.STATIC )
44+
|| requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.TRANSITIVE ) )
4245
{
43-
builder.requires​( Collections.singleton( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ),
44-
requires.name() );
46+
Set<JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers = new LinkedHashSet<>();
47+
if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.STATIC ) )
48+
{
49+
modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC );
50+
}
51+
if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.TRANSITIVE ) )
52+
{
53+
modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE );
54+
}
55+
builder.requires​( modifiers, requires.name() );
4556
}
4657
else
4758
{

plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParserTest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.codehaus.plexus.languages.java.jpms;
22

3-
import static org.junit.Assert.assertArrayEquals;
43

54
/*
65
* Licensed to the Apache Software Foundation (ASF) under one
@@ -21,9 +20,12 @@
2120
* under the License.
2221
*/
2322

23+
import static org.junit.Assert.assertArrayEquals;
2424
import static org.junit.Assert.assertEquals;
2525
import static org.junit.Assert.assertNotNull;
2626
import static org.junit.Assert.assertNull;
27+
import static org.hamcrest.MatcherAssert.assertThat;
28+
import static org.hamcrest.Matchers.is;
2729

2830
import java.io.IOException;
2931
import java.io.InputStream;
@@ -177,4 +179,26 @@ public void testProvides() throws Exception
177179

178180
}
179181

182+
@Test
183+
public void testRequires() throws Exception
184+
{
185+
try ( InputStream is = Files.newInputStream( Paths.get( "src/test/resources/dir.descriptor.requires/out/module-info.class" ) ) )
186+
{
187+
JavaModuleDescriptor descriptor = parser.parse( is );
188+
189+
assertNotNull( descriptor);
190+
assertThat( descriptor.requires().size(), is( 5 ) );
191+
192+
Set<JavaRequires> expectedRequires = JavaModuleDescriptor.newAutomaticModule( "_" )
193+
.requires( "java.base" )
194+
.requires( "mod_r" )
195+
.requires​( Collections.singleton( JavaRequires.JavaModifier.STATIC ), "mod_r_s" )
196+
.requires​( Collections.singleton( JavaRequires.JavaModifier.TRANSITIVE ), "mod_r_t" )
197+
.requires​( new HashSet<JavaRequires.JavaModifier>( Arrays.asList( JavaRequires.JavaModifier.STATIC, JavaRequires.JavaModifier.TRANSITIVE ) ), "mod_r_s_t" )
198+
.build()
199+
.requires();
200+
201+
assertEquals( expectedRequires, descriptor.requires() );
202+
}
203+
}
180204
}

plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import java.nio.file.Paths;
3131
import java.util.Arrays;
3232
import java.util.Collections;
33+
import java.util.HashSet;
34+
35+
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier;
3336

3437
import org.junit.Before;
3538
import org.junit.Test;
@@ -377,7 +380,7 @@ public void testTransitiveStatic() throws Exception
377380
when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" )
378381
.requires( "moduleB" ).build() );
379382
when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" )
380-
.requires​( Collections.singleton( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ), "moduleC" ).build() );
383+
.requires​( Collections.singleton( JavaModifier.STATIC ), "moduleC" ).build() );
381384
when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ).build() );
382385

383386

@@ -399,10 +402,10 @@ public void testDirectStatic() throws Exception
399402

400403
when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" )
401404
.requires( "moduleB" )
402-
.requires​( Collections.singleton( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ), "moduleD")
405+
.requires​( Collections.singleton( JavaModifier.STATIC ), "moduleD")
403406
.build() );
404407
when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" )
405-
.requires​( Collections.singleton( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ), "moduleC" )
408+
.requires​( Collections.singleton( JavaModifier.STATIC ), "moduleC" )
406409
.build() );
407410
when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ).build() );
408411
when( asmParser.getModuleDescriptor( moduleD ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleD" ).build() );
@@ -443,5 +446,37 @@ public void testDuplicateModule() throws Exception
443446
assertThat( result.getClasspathElements().size(), is( 0 ) );
444447
assertThat( result.getPathExceptions().size(), is( 0 ) );
445448
}
449+
450+
@Test
451+
public void testStaticTransitive() throws Exception
452+
{
453+
Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java
454+
Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file
455+
Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file
456+
Path moduleD = Paths.get( "src/test/resources/mock/jar2.jar" ); // any existing file
457+
ResolvePathsRequest<Path> request = ResolvePathsRequest.ofPaths( moduleB, moduleC, moduleD ).setMainModuleDescriptor( moduleA );
458+
459+
when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" )
460+
.requires( "moduleB" )
461+
.build() );
462+
when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" )
463+
.requires​( new HashSet<JavaModifier>( Arrays.asList( JavaModifier.STATIC,JavaModifier.TRANSITIVE ) ), "moduleC" )
464+
.build() );
465+
when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" )
466+
.requires​( new HashSet<JavaModifier>( Arrays.asList( JavaModifier.STATIC,JavaModifier.TRANSITIVE ) ), "moduleD" )
467+
.build() );
468+
when( asmParser.getModuleDescriptor( moduleD ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleD" ).build() );
469+
470+
471+
ResolvePathsResult<Path> result = locationManager.resolvePaths( request );
472+
assertThat( result.getPathElements().size(), is( 3 ) );
473+
assertThat( result.getModulepathElements().size(), is( 2 ) );
474+
assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) );
475+
assertThat( result.getModulepathElements().containsKey( moduleC ), is( true ) );
476+
assertThat( result.getClasspathElements().size(), is( 1 ) );
477+
assertThat( result.getClasspathElements().contains( moduleD ), is( true ) );
478+
assertThat( result.getPathExceptions().size(), is( 0 ) );
479+
}
480+
446481

447482
}

plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,22 @@ public void test() throws Exception
5050
JavaRequires requires = requiresIter.next();
5151
assertEquals( "d.e", requires.name() );
5252
assertFalse( requires.modifiers​().contains( JavaRequires.JavaModifier.STATIC ) );
53+
assertFalse( requires.modifiers​().contains( JavaRequires.JavaModifier.TRANSITIVE ) );
5354

5455
requires = requiresIter.next();
5556
assertEquals( "s.d.e", requires.name() );
5657
assertTrue( requires.modifiers​().contains( JavaRequires.JavaModifier.STATIC ) );
58+
assertFalse( requires.modifiers​().contains( JavaRequires.JavaModifier.TRANSITIVE ) );
59+
60+
requires = requiresIter.next();
61+
assertEquals( "t.d.e", requires.name() );
62+
assertFalse( requires.modifiers​().contains( JavaRequires.JavaModifier.STATIC ) );
63+
assertTrue( requires.modifiers​().contains( JavaRequires.JavaModifier.TRANSITIVE ) );
64+
65+
requires = requiresIter.next();
66+
assertEquals( "s.t.d.e", requires.name() );
67+
assertTrue( requires.modifiers​().contains( JavaRequires.JavaModifier.STATIC ) );
68+
assertTrue( requires.modifiers​().contains( JavaRequires.JavaModifier.TRANSITIVE ) );
5769

5870
Iterator<JavaExports> exportsIter = moduleDescriptor.exports().iterator();
5971

Binary file not shown.

plexus-java/src/test/resources/src.dir/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
{
66
requires d.e;
77
requires static s.d.e;
8+
requires transitive t.d.e;
9+
requires static transitive s.t.d.e;
810

911
exports f.g;
1012
exports f.g.h to i.j, k.l.m;

0 commit comments

Comments
 (0)