View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit.internal.startup;
7   
8   import static java.util.Arrays.asList;
9   
10  import static mockit.internal.util.ClassLoad.loadClassAtStartup;
11  import static mockit.internal.util.ClassLoad.searchTypeInClasspath;
12  
13  import edu.umd.cs.findbugs.annotations.NonNull;
14  
15  import java.lang.instrument.Instrumentation;
16  import java.util.Collection;
17  import java.util.Collections;
18  import java.util.HashSet;
19  import java.util.Set;
20  
21  import mockit.MockUp;
22  import mockit.coverage.CodeCoverage;
23  import mockit.integration.junit4.FakeFrameworkMethod;
24  import mockit.integration.junit4.FakeRunNotifier;
25  import mockit.internal.reflection.ConstructorReflection;
26  import mockit.internal.util.StackTrace;
27  
28  final class JMockitInitialization {
29      private JMockitInitialization() {
30      }
31  
32      static void initialize(@NonNull Instrumentation inst, boolean activateCoverage) {
33          if (activateCoverage || CodeCoverage.active()) {
34              inst.addTransformer(new CodeCoverage());
35          }
36  
37          applyInternalStartupFakesAsNeeded();
38          applyUserSpecifiedStartupFakesIfAny();
39      }
40  
41      private static void applyInternalStartupFakesAsNeeded() {
42          if (searchTypeInClasspath("org.junit.runners.model.FrameworkMethod", true) != null
43                  || searchTypeInClasspath("org.junit.vintage.engine.VintageTestEngine", true) != null) {
44              new FakeRunNotifier();
45              new FakeFrameworkMethod();
46          }
47  
48          if (searchTypeInClasspath("org.junit.jupiter.api.extension.Extension", true) != null) {
49              System.setProperty("junit.jupiter.extensions.autodetection.enabled", "true");
50          }
51      }
52  
53      private static void applyUserSpecifiedStartupFakesIfAny() {
54          Collection<String> fakeClasses = getFakeClasses();
55  
56          for (String fakeClassName : fakeClasses) {
57              applyStartupFake(fakeClassName);
58          }
59      }
60  
61      @NonNull
62      private static Collection<String> getFakeClasses() {
63          String commaOrSpaceSeparatedValues = System.getProperty("fakes");
64  
65          if (commaOrSpaceSeparatedValues == null) {
66              return Collections.emptyList();
67          }
68  
69          // noinspection DynamicRegexReplaceableByCompiledPattern
70          String[] fakeClassNames = commaOrSpaceSeparatedValues.split("\\s*,\\s*|\\s+");
71          Set<String> uniqueClassNames = new HashSet<>(asList(fakeClassNames));
72          uniqueClassNames.remove("");
73          return uniqueClassNames;
74      }
75  
76      private static void applyStartupFake(@NonNull String fakeClassName) {
77          String argument = null;
78          int p = fakeClassName.indexOf('=');
79  
80          if (p > 0) {
81              argument = fakeClassName.substring(p + 1);
82              fakeClassName = fakeClassName.substring(0, p);
83          }
84  
85          try {
86              Class<?> fakeClass = loadClassAtStartup(fakeClassName);
87  
88              if (MockUp.class.isAssignableFrom(fakeClass)) {
89                  if (argument == null) {
90                      ConstructorReflection.newInstanceUsingDefaultConstructor(fakeClass);
91                  } else {
92                      ConstructorReflection.newInstanceUsingCompatibleConstructor(fakeClass, argument);
93                  }
94              }
95          } catch (UnsupportedOperationException ignored) {
96          } catch (Throwable unexpectedFailure) {
97              StackTrace.filterStackTrace(unexpectedFailure);
98              unexpectedFailure.printStackTrace();
99          }
100     }
101 }