2020import  org .gradle .work .DisableCachingByDefault ;
2121import  org .jetbrains .annotations .NotNull ;
2222import  org .jetbrains .annotations .Nullable ;
23+ import  org .slf4j .Logger ;
24+ import  org .slf4j .LoggerFactory ;
2325
2426import  java .io .File ;
27+ import  java .io .IOException ;
28+ import  java .io .InputStream ;
29+ import  java .nio .file .Files ;
30+ import  java .nio .file .Path ;
31+ import  java .nio .file .Paths ;
2532import  java .util .Arrays ;
2633import  java .util .Collection ;
34+ import  java .util .Enumeration ;
35+ import  java .util .HashSet ;
2736import  java .util .LinkedHashSet ;
2837import  java .util .List ;
2938import  java .util .Map ;
39+ import  java .util .Objects ;
3040import  java .util .Set ;
41+ import  java .util .jar .JarEntry ;
42+ import  java .util .jar .JarFile ;
3143import  javax .inject .Inject ;
3244
3345import  static  java .util .Collections .emptySet ;
@@ -69,6 +81,7 @@ public class DependencyCalculator extends DefaultTask {
6981        { "co.paralleluniverse" , "quasar-core"  },
7082        { "co.paralleluniverse" , "quasar-core-osgi"  }
7183    };
84+     private  static  final  Logger  log  = LoggerFactory .getLogger (DependencyCalculator .class );
7285
7386    /** 
7487     * Gradle's configuration cache forbids invoking {@link org.gradle.api.Task#getProject} 
@@ -224,6 +237,18 @@ public void calculate() {
224237        final  Set <File > cordappFiles  = resolveFirstLevelFilesFor (externalConfiguration , cordappDeps );
225238        final  List <ProjectDependency > projectCordappDeps  = filterIsInstance (cordappDeps , ProjectDependency .class );
226239        final  Set <File > projectCordappFiles  = toFiles (resolveFirstLevel (externalConfiguration , projectCordappDeps ));
240+         Set <String > cordappFileNames  = new  HashSet <>();
241+         for (File  file : cordappFiles ) {
242+             cordappFileNames .add (file .getName ());
243+         }
244+         Set <File > cpbs  = getCpbs (externalConfiguration );
245+         Set <File > transitives  = new  HashSet <>();
246+         try  {
247+             transitives  = extractJarsFromCpb (cpbs , cordappFileNames );
248+         } catch  (IOException  e ) {
249+             log .warn ("Could not resolve transitive dependencies from CPBs: {}" , e .getMessage ());
250+         }
251+         cordappFiles .addAll (transitives );
227252        _projectCordapps .setFrom (projectCordappFiles );
228253        _projectCordapps .disallowChanges ();
229254
@@ -236,6 +261,58 @@ public void calculate() {
236261        _providedJars .disallowChanges ();
237262    }
238263
264+     @ NotNull 
265+     private  static  Set <File > getCpbs (ResolvedConfiguration  externalConfiguration ) {
266+         Set <File > cpbs  = new  HashSet <>();
267+         for  (File  file : externalConfiguration .getFiles ()) {
268+             if  (!file .getAbsolutePath ().contains ("/." )) {
269+                 File  dir  = file .getAbsoluteFile ().getParentFile ();
270+                 for  (File  siblingFile : Objects .requireNonNull (dir .listFiles ())) {
271+                     if  (siblingFile .isFile () && siblingFile .getAbsolutePath ().endsWith (".cpb" )) {
272+                         cpbs .add (siblingFile );
273+                     }
274+                 }
275+             }
276+         }
277+         return  cpbs ;
278+     }
279+ 
280+     @ NotNull 
281+     private  static  Set <File > extractJarsFromCpb (Set <File > cpbs , Set <String > cordappFileNames ) throws  IOException  {
282+         Path  pathToDir  = Files .createTempDirectory ("jars" );
283+         pathToDir .toFile ().deleteOnExit ();
284+         Set <File > transitives  = new  HashSet <>();
285+         for  (File  cpb : cpbs ) {
286+             JarFile  jarFile  = new  JarFile (cpb );
287+             Enumeration <JarEntry > jarEntries  = jarFile .entries ();
288+             while  (jarEntries .hasMoreElements ()) {
289+                 JarEntry  jarEntry  = jarEntries .nextElement ();
290+                 if  (!cordappFileNames .contains (jarEntry .getName ())) {
291+                     if  (jarEntry .getName ().endsWith (".jar" )) {
292+                         transitives .add (extractJarEntry (jarFile , jarEntry , pathToDir ));
293+                     }
294+                 }
295+             }
296+         }
297+         return  transitives ;
298+     }
299+ 
300+     private  static  File  extractJarEntry (JarFile  jarFile , JarEntry  jarEntry , Path  pathToDir ) throws  IOException  {
301+         File  file ;
302+         Path  path  = Paths .get (pathToDir .toString (), jarEntry .getName ());
303+         if  (!Files .exists (pathToDir )) {
304+             Files .createDirectories (pathToDir );
305+         }
306+         if  (!Files .exists (path )) {
307+             InputStream  inputStream  = jarFile .getInputStream (jarEntry );
308+             Files .copy (inputStream , path );
309+             path .toFile ().deleteOnExit ();
310+         }
311+         file  = path .toFile ();
312+         file .deleteOnExit ();
313+         return  file ;
314+     }
315+ 
239316    @ NotNull 
240317    private  static  Set <File > resolveAllFilesFor (
241318        @ NotNull  ResolvedConfiguration  resolved ,
0 commit comments