1 package org.apache.maven.plugin.surefire.booterclient;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.Commandline;
23 import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
24 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
25 import org.apache.maven.surefire.api.util.TempFileManager;
26 import org.apache.maven.surefire.booter.AbstractPathConfiguration;
27 import org.apache.maven.surefire.booter.Classpath;
28 import org.apache.maven.surefire.booter.ModularClasspath;
29 import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
30 import org.apache.maven.surefire.booter.StartupConfiguration;
31 import org.apache.maven.surefire.booter.SurefireBooterForkException;
32 import org.apache.maven.surefire.extensions.ForkNodeFactory;
33
34 import javax.annotation.Nonnegative;
35 import javax.annotation.Nonnull;
36 import javax.annotation.Nullable;
37 import java.io.File;
38 import java.io.FileWriter;
39 import java.io.IOException;
40 import java.util.Collection;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Properties;
45
46 import static java.io.File.pathSeparatorChar;
47 import static org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
48 import static org.apache.maven.surefire.api.util.internal.StringUtils.NL;
49 import static org.apache.maven.surefire.shared.utils.StringUtils.replace;
50
51
52
53
54
55 public class ModularClasspathForkConfiguration
56 extends DefaultForkConfiguration
57 {
58 @SuppressWarnings( "checkstyle:parameternumber" )
59 public ModularClasspathForkConfiguration( @Nonnull Classpath bootClasspath,
60 @Nonnull File tempDirectory,
61 @Nullable String debugLine,
62 @Nonnull File workingDirectory,
63 @Nonnull Properties modelProperties,
64 @Nullable String argLine,
65 @Nonnull Map<String, String> environmentVariables,
66 @Nonnull String[] excludedEnvironmentVariables,
67 boolean debug,
68 @Nonnegative int forkCount,
69 boolean reuseForks,
70 @Nonnull Platform pluginPlatform,
71 @Nonnull ConsoleLogger log,
72 @Nonnull ForkNodeFactory forkNodeFactory )
73 {
74 super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
75 environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
76 forkNodeFactory );
77 }
78
79 @Override
80 protected void resolveClasspath( @Nonnull Commandline cli, @Nonnull String startClass,
81 @Nonnull StartupConfiguration config, @Nonnull File dumpLogDirectory )
82 throws SurefireBooterForkException
83 {
84 try
85 {
86 AbstractPathConfiguration pathConfig = config.getClasspathConfiguration();
87
88 ModularClasspathConfiguration modularClasspathConfiguration =
89 pathConfig.toRealPath( ModularClasspathConfiguration.class );
90
91 ModularClasspath modularClasspath = modularClasspathConfiguration.getModularClasspath();
92
93 boolean isMainDescriptor = modularClasspath.isMainDescriptor();
94 String moduleName = modularClasspath.getModuleNameFromDescriptor();
95 List<String> modulePath = modularClasspath.getModulePath();
96 Collection<String> packages = modularClasspath.getPackages();
97 File patchFile = modularClasspath.getPatchFile();
98 List<String> classpath = toCompleteClasspath( config );
99
100 File argsFile = createArgsFile( moduleName, modulePath, classpath, packages, patchFile, startClass,
101 isMainDescriptor, config.getJpmsArguments() );
102
103 cli.createArg().setValue( "@" + escapeToPlatformPath( argsFile.getAbsolutePath() ) );
104 }
105 catch ( IOException e )
106 {
107 String error = "Error creating args file";
108 InPluginProcessDumpSingleton.getSingleton()
109 .dumpException( e, error, dumpLogDirectory );
110 throw new SurefireBooterForkException( error, e );
111 }
112 }
113
114 @Nonnull
115 File createArgsFile( @Nonnull String moduleName, @Nonnull List<String> modulePath,
116 @Nonnull List<String> classPath, @Nonnull Collection<String> packages,
117 File patchFile, @Nonnull String startClassName, boolean isMainDescriptor,
118 @Nonnull List<String[]> providerJpmsArguments )
119 throws IOException
120 {
121 File surefireArgs = TempFileManager.instance( getTempDirectory() ).createTempFile( "surefireargs", "" );
122 if ( isDebug() )
123 {
124 getLogger().debug( "Path to args file: " + surefireArgs.getCanonicalPath() );
125 }
126 else
127 {
128 surefireArgs.deleteOnExit();
129 }
130
131 try ( FileWriter io = new FileWriter( surefireArgs ) )
132 {
133 StringBuilder args = new StringBuilder( 64 * 1024 );
134 if ( !modulePath.isEmpty() )
135 {
136
137 args.append( "--module-path" )
138 .append( NL )
139 .append( '"' );
140
141 for ( Iterator<String> it = modulePath.iterator(); it.hasNext(); )
142 {
143 args.append( replace( it.next(), "\\", "\\\\" ) );
144 if ( it.hasNext() )
145 {
146 args.append( pathSeparatorChar );
147 }
148 }
149
150 args.append( '"' )
151 .append( NL );
152 }
153
154 if ( !classPath.isEmpty() )
155 {
156 args.append( "--class-path" )
157 .append( NL )
158 .append( '"' );
159
160 for ( Iterator<String> it = classPath.iterator(); it.hasNext(); )
161 {
162 args.append( replace( it.next(), "\\", "\\\\" ) );
163 if ( it.hasNext() )
164 {
165 args.append( pathSeparatorChar );
166 }
167 }
168
169 args.append( '"' )
170 .append( NL );
171 }
172
173 if ( isMainDescriptor )
174 {
175 args.append( "--patch-module" )
176 .append( NL )
177 .append( moduleName )
178 .append( '=' )
179 .append( '"' )
180 .append( replace( patchFile.getPath(), "\\", "\\\\" ) )
181 .append( '"' )
182 .append( NL );
183
184 for ( String pkg : packages )
185 {
186 args.append( "--add-opens" )
187 .append( NL )
188 .append( moduleName )
189 .append( '/' )
190 .append( pkg )
191 .append( '=' )
192 .append( "ALL-UNNAMED" )
193 .append( NL );
194 }
195
196 args.append( "--add-modules" )
197 .append( NL )
198 .append( moduleName )
199 .append( NL );
200
201 args.append( "--add-reads" )
202 .append( NL )
203 .append( moduleName )
204 .append( '=' )
205 .append( "ALL-UNNAMED" )
206 .append( NL );
207 }
208 else
209 {
210 args.append( "--add-modules" )
211 .append( NL )
212 .append( moduleName )
213 .append( NL );
214 }
215
216 for ( String[] entries : providerJpmsArguments )
217 {
218 for ( String entry : entries )
219 {
220 args.append( entry )
221 .append( NL );
222 }
223 }
224
225 args.append( startClassName );
226
227 String argsFileContent = args.toString();
228
229 if ( isDebug() )
230 {
231 getLogger().debug( "args file content:" + NL + argsFileContent );
232 }
233
234 io.write( argsFileContent );
235
236 return surefireArgs;
237 }
238 }
239 }