├── .github └── workflows │ └── [A] update documentation.yml ├── .gitignore ├── README.md ├── customize-hostname-resolution ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── jjbrt │ │ └── dns │ │ ├── DNSJavaHostResolver.java │ │ ├── HostNameResolutionCustomizer.java │ │ ├── HostNameResolutionWithCustomHostResolverWithYAMLConfiguration.java │ │ └── HostNameResolutionWithDNSClientHostResolverWithYAMLConfiguration.java │ └── resources │ ├── burningwave.static.properties │ ├── config.yml │ └── logback-test.xml ├── dependency_injection ├── doc │ ├── class-diagram.drawio │ └── class-diagram.png ├── pom.xml └── src │ └── main │ └── java │ ├── com │ └── useraccount │ │ ├── UserAccountApplication.java │ │ ├── UserAccountClientComponent.java │ │ └── services │ │ ├── AccountService.java │ │ ├── UserService.java │ │ └── impl │ │ ├── AccountServiceImpl.java │ │ └── UserServiceImpl.java │ └── org │ └── di │ └── framework │ ├── Injector.java │ ├── annotations │ ├── Autowired.java │ ├── Component.java │ └── Qualifier.java │ └── utils │ └── InjectionUtil.java ├── docs ├── Java-logo.png ├── _config.yml ├── _layouts │ └── default.html ├── assets │ ├── css │ │ └── style.scss │ └── fonts │ │ ├── Tomcat-Bold.eot │ │ ├── Tomcat-Bold.ttf │ │ ├── Tomcat-Bold.woff │ │ ├── Tomcat-Bold.woff2 │ │ ├── Tomcat-Regular.eot │ │ ├── Tomcat-Regular.ttf │ │ ├── Tomcat-Regular.woff │ │ └── Tomcat-Regular.woff2 └── index.md ├── json ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── jjbrt │ │ └── json │ │ ├── ObjectHandlerExample.java │ │ ├── ValidatorExample.java │ │ └── bean │ │ ├── Maths.java │ │ ├── Question.java │ │ ├── Quiz.java │ │ ├── Root.java │ │ └── Sport.java │ └── resources │ ├── quiz-to-be-validated.json │ └── quiz.json ├── parallel-iteration ├── pom.xml └── src │ └── main │ └── java │ ├── burningwave.static.properties │ └── com │ └── github │ └── jjbrt │ └── iteration │ ├── ArraysIterator.java │ └── ListsIterator.java ├── reflection ├── pom.xml └── src │ └── main │ └── java │ ├── burningwave.static.properties │ └── com │ └── github │ └── jjbrt │ └── reflection │ ├── AllModulesToAllModulesExporter.java │ ├── FieldsHandler.java │ ├── MethodHandleInvoker.java │ ├── MethodHandleRetrieverAndInvoker.java │ ├── MethodInvoker.java │ ├── MethodRetrieverAndInvoker.java │ └── PackageToModuleExporter.java └── spring-boot-application-adapter ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── springbootappadapter │ │ ├── SpringBootWebApplication.java │ │ └── WelcomeController.java ├── resources │ ├── application.properties │ ├── logback-test.xml │ └── static │ │ └── css │ │ └── main.css └── webapp │ └── WEB-INF │ └── jsp │ └── welcome.jsp └── test ├── java └── org │ └── springbootappadapter │ └── DependenciesAdapter.java └── resources ├── burningwave.properties └── burningwave.static.properties /.github/workflows/[A] update documentation.yml: -------------------------------------------------------------------------------- 1 | name: Update index page 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - "**README.md" 9 | 10 | jobs: 11 | update-index-page: 12 | runs-on: ubuntu-latest 13 | name: Update index page 14 | steps: 15 | - uses: actions/checkout@master 16 | - name: Overwrite the index.md 17 | run: | 18 | git config user.name "${{ github.event.head_commit.committer.name }}" 19 | git config user.email "${{ github.event.head_commit.committer.email }}" 20 | git pull origin ${{github.ref}} 21 | cp "./README.md" "./docs/index.md" 22 | git add . 23 | git commit -am "Update" --allow-empty 24 | git push 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Log file 2 | *.log 3 | 4 | # BlueJ files 5 | *.ctxt 6 | 7 | # Mobile Tools for Java (J2ME) 8 | .mtj.tmp/ 9 | 10 | # Package Files # 11 | *.jar 12 | *.war 13 | *.nar 14 | *.ear 15 | *.tar.gz 16 | *.rar 17 | 18 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 19 | hs_err_pid* 20 | 21 | */target/ 22 | *.project 23 | *.cmd 24 | /.settings 25 | */.settings 26 | */.classpath 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced Java tutorials 2 | 3 | Java-logo.png 4 | 5 | 6 | A collection of examples about advanced Java programming. Here you will find tutorials about: 7 | 8 | * [how to create your own dependency injection framework](https://jim-jerald-burton.medium.com/how-to-create-your-own-dependency-injection-framework-in-java-12a6e52aeff9) 9 | * [how to make applications created with old Java versions work on Java 9 and later versions](https://dev.to/bw_software/making-applications-created-with-old-java-versions-work-on-java-9-and-later-versions-19ld) 10 | * [how to make reflection fully work on Java 9 and later](https://jim-jerald-burton.medium.com/making-reflection-fully-work-on-java-9-and-later-767320344d1d) 11 | * [how to export all modules to all modules at runtime on Java 9 and later](https://jim-jerald-burton.medium.com/exporting-all-modules-to-all-modules-at-runtime-on-java-9-and-later-3517eb479701) 12 | * [how to iterate collections and arrays in parallel by setting thread priority](https://dev.to/bw_software/iterating-collections-and-arrays-in-parallel-5acg) 13 | * [how to configure host name resolution to use a universal custom host name resolver](https://dev.to/jjbrt/how-to-configure-hostname-resolution-to-use-a-universal-custom-hostname-resolver-in-java-14p0) 14 | * [how to query and validate a JSON document](https://dev.to/jjbrt/querying-and-validating-a-json-document-in-java-323i) 15 | 16 |
17 | 18 | **Any instructions to make each project work are indicated in the possible README.md file inside it**. 19 | -------------------------------------------------------------------------------- /customize-hostname-resolution/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.github.jjbrt.java-tutorials 6 | customize-hostname-resolution 7 | 8 | Customizing host resolution tutorial 9 | Customizing host resolution tutorial 10 | 1.0.0 11 | 12 | 13 | 9 14 | 9 15 | 2.13.4 16 | 17 | 18 | 19 | 20 | 21 | org.burningwave 22 | tools 23 | 0.27.2 24 | 25 | 26 | 27 | com.fasterxml.jackson.core 28 | jackson-core 29 | ${jackson.version} 30 | 31 | 32 | 33 | com.fasterxml.jackson.dataformat 34 | jackson-dataformat-yaml 35 | ${jackson.version} 36 | 37 | 38 | 39 | dnsjava 40 | dnsjava 41 | 3.5.1 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-dependency-plugin 51 | 3.1.2 52 | 53 | 54 | 55 | sources 56 | resolve 57 | 58 | 59 | javadoc 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/java/com/github/jjbrt/dns/DNSJavaHostResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.dns; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Driver; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Strings; 5 | 6 | import java.net.InetAddress; 7 | import java.net.UnknownHostException; 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.concurrent.CompletableFuture; 13 | import java.util.function.Consumer; 14 | import java.util.function.Supplier; 15 | 16 | import org.burningwave.tools.net.DNSClientHostResolver; 17 | import org.burningwave.tools.net.HostResolver; 18 | import org.burningwave.tools.net.IPAddressUtil; 19 | import org.xbill.DNS.AAAARecord; 20 | import org.xbill.DNS.ARecord; 21 | import org.xbill.DNS.Name; 22 | import org.xbill.DNS.PTRRecord; 23 | import org.xbill.DNS.Record; 24 | import org.xbill.DNS.Resolver; 25 | import org.xbill.DNS.ReverseMap; 26 | import org.xbill.DNS.SimpleResolver; 27 | import org.xbill.DNS.TextParseException; 28 | import org.xbill.DNS.Type; 29 | import org.xbill.DNS.lookup.LookupResult; 30 | import org.xbill.DNS.lookup.LookupSession; 31 | 32 | @SuppressWarnings("unchecked") 33 | public class DNSJavaHostResolver implements HostResolver { 34 | private static final int[] DEFAULT_IP_TYPE_TO_SEARCH_FOR; 35 | 36 | static { 37 | DEFAULT_IP_TYPE_TO_SEARCH_FOR = new int[] {Type.A, Type.AAAA}; 38 | } 39 | 40 | private LookupSession lookupSession; 41 | private int[] ipTypeToSearchFor; 42 | 43 | public DNSJavaHostResolver(String dNSServerIP) { 44 | this(dNSServerIP, DNSClientHostResolver.DEFAULT_PORT, DEFAULT_IP_TYPE_TO_SEARCH_FOR); 45 | } 46 | 47 | public DNSJavaHostResolver(String dNSServerIP, int port, int... ipTypes) { 48 | try { 49 | Resolver resolver = new SimpleResolver(InetAddress.getByName(dNSServerIP)); 50 | resolver.setPort(port); 51 | lookupSession = LookupSession.builder().resolver( 52 | resolver 53 | ).build(); 54 | ipTypeToSearchFor = ipTypes != null && ipTypes.length > 0 ? 55 | ipTypes : new int[] {Type.A, Type.AAAA}; 56 | } catch (UnknownHostException exc) { 57 | Driver.throwException(exc); 58 | } 59 | } 60 | 61 | 62 | public static Collection newInstances(Supplier>> configuration) { 63 | Collection dNSClientHostResolvers = new ArrayList<>(); 64 | configuration.get().stream().forEach(serverMap -> { 65 | dNSClientHostResolvers.add( 66 | new DNSJavaHostResolver( 67 | (String)serverMap.get("ip"), 68 | (Integer)serverMap.getOrDefault("port", DNSClientHostResolver.DEFAULT_PORT), 69 | ((List)serverMap.get("ipTypeToSearchFor")).stream() 70 | .mapToInt(iptype -> { 71 | if (iptype.toUpperCase().equals("IPV4")) { 72 | return Type.A; 73 | } else if (iptype.toUpperCase().equals("IPV6")) { 74 | return Type.AAAA; 75 | } 76 | throw new IllegalArgumentException(Strings.compile("{} is not a valid ip type", iptype)); 77 | }).toArray() 78 | ) 79 | ); 80 | }); 81 | return dNSClientHostResolvers; 82 | } 83 | 84 | @Override 85 | public Collection getAllAddressesForHostName(Map argumentMap) { 86 | return getAllAddressesForHostName((String)getMethodArguments(argumentMap)[0]); 87 | } 88 | 89 | public Collection getAllAddressesForHostName(String hostName) { 90 | Collection hostInfos = new ArrayList<>(); 91 | findAndProcessHostInfos( 92 | () -> { 93 | try { 94 | return Name.fromString(hostName.endsWith(".") ? hostName : hostName + "."); 95 | } catch (TextParseException exc) { 96 | return Driver.throwException(exc); 97 | } 98 | }, 99 | record -> { 100 | if (record instanceof ARecord) { 101 | hostInfos.add(((ARecord)record).getAddress()); 102 | } else if (record instanceof AAAARecord) { 103 | hostInfos.add(((AAAARecord)record).getAddress()); 104 | } 105 | }, 106 | ipTypeToSearchFor 107 | ); 108 | return hostInfos; 109 | } 110 | 111 | 112 | @Override 113 | public Collection getAllHostNamesForHostAddress(Map argumentMap) { 114 | return getAllHostNamesForHostAddress((byte[])getMethodArguments(argumentMap)[0]); 115 | } 116 | 117 | public Collection getAllHostNamesForHostAddress(String iPAddress) { 118 | return getAllHostNamesForHostAddress(IPAddressUtil.INSTANCE.textToNumericFormat(iPAddress)); 119 | } 120 | 121 | public Collection getAllHostNamesForHostAddress(byte[] address) { 122 | Collection hostNames = new ArrayList<>(); 123 | findAndProcessHostInfos( 124 | () -> 125 | ReverseMap.fromAddress(address), 126 | record -> 127 | hostNames.add(((PTRRecord)record).getTarget().toString(true)), 128 | Type.PTR 129 | ); 130 | return hostNames; 131 | } 132 | 133 | private void findAndProcessHostInfos( 134 | Supplier nameSupplier, 135 | Consumer recordProcessor, 136 | int... types 137 | ) { 138 | Collection> hostInfoRetrievers = new ArrayList<>(); 139 | for (int type : types) { 140 | hostInfoRetrievers.add( 141 | lookupSession.lookupAsync(nameSupplier.get(), type).toCompletableFuture() 142 | ); 143 | } 144 | hostInfoRetrievers.stream().forEach(hostNamesRetriever -> { 145 | try { 146 | List records = hostNamesRetriever.join().getRecords(); 147 | if (records != null) { 148 | for (Record record : records) { 149 | recordProcessor.accept(record); 150 | } 151 | } 152 | } catch (Throwable exc) { 153 | 154 | } 155 | }); 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/java/com/github/jjbrt/dns/HostNameResolutionCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.dns; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 4 | 5 | import java.net.InetAddress; 6 | import java.net.UnknownHostException; 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | 10 | import org.burningwave.tools.net.DefaultHostResolver; 11 | import org.burningwave.tools.net.HostResolutionRequestInterceptor; 12 | import org.burningwave.tools.net.MappedHostResolver; 13 | 14 | public class HostNameResolutionCustomizer { 15 | 16 | public static void main(String[] args) { 17 | try { 18 | execute(loadConfiguration()); 19 | } catch (Throwable exc) { 20 | exc.printStackTrace(); 21 | } 22 | } 23 | 24 | public static Map loadConfiguration() { 25 | Map hostAliases = new LinkedHashMap<>(); 26 | hostAliases.put("my.hostname.one", "123.123.123.123"); 27 | hostAliases.put("my.hostname.two", "123.123.123.123"); 28 | hostAliases.put("my.hostname.three", "12.21.34.43"); 29 | hostAliases.put("my.hostname.four", "12.21.34.43"); 30 | return hostAliases; 31 | } 32 | 33 | public static void execute(Map hostAliases) { 34 | 35 | //Installing the host resolvers 36 | HostResolutionRequestInterceptor.INSTANCE.install( 37 | new MappedHostResolver(hostAliases), 38 | //This is the system default resolving wrapper 39 | DefaultHostResolver.INSTANCE 40 | ); 41 | 42 | printHostInfo("my.hostname.one"); 43 | printHostInfo("my.hostname.two"); 44 | printHostInfo("my.hostname.three"); 45 | printHostInfo("my.hostname.four"); 46 | printHostInfo("google.com"); 47 | 48 | //Restoring hostname resolving to default and cleaning the cache 49 | HostResolutionRequestInterceptor.INSTANCE.uninstall(); 50 | 51 | //Now we have reset the hostnames in the map will not be resolved... 52 | printHostInfo("my.hostname.one"); 53 | printHostInfo("my.hostname.two"); 54 | printHostInfo("my.hostname.three"); 55 | printHostInfo("my.hostname.four"); 56 | //... Except this 57 | printHostInfo("google.com"); 58 | 59 | //Adding host aliases again 60 | HostResolutionRequestInterceptor.INSTANCE.install( 61 | new MappedHostResolver(hostAliases), 62 | DefaultHostResolver.INSTANCE 63 | ); 64 | 65 | //Retesting 66 | printHostInfo("my.hostname.one"); 67 | printHostInfo("my.hostname.two"); 68 | printHostInfo("my.hostname.three"); 69 | printHostInfo("my.hostname.four"); 70 | printHostInfo("google.com"); 71 | } 72 | 73 | public static void printHostInfo(String hostname) { 74 | try { 75 | InetAddress inetAddress = InetAddress.getByName(hostname); 76 | ManagedLoggerRepository.logInfo(HostNameResolutionCustomizer.class::getName, "\n\n\tThe ip of hostname {} is {}\n\n", inetAddress.getHostName(), inetAddress.getHostAddress()); 77 | } catch (UnknownHostException exc) { 78 | ManagedLoggerRepository.logError(HostNameResolutionCustomizer.class::getName,"\n\n\tUnable to resolve hostname {}\n\n", hostname); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/java/com/github/jjbrt/dns/HostNameResolutionWithCustomHostResolverWithYAMLConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.dns; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Driver; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.net.InetAddress; 9 | import java.net.UnknownHostException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import org.burningwave.core.assembler.ComponentContainer; 15 | import org.burningwave.tools.net.DefaultHostResolver; 16 | import org.burningwave.tools.net.HostResolutionRequestInterceptor; 17 | import org.burningwave.tools.net.HostResolver; 18 | import org.burningwave.tools.net.MappedHostResolver; 19 | 20 | import com.fasterxml.jackson.databind.ObjectMapper; 21 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 22 | 23 | 24 | @SuppressWarnings("unchecked") 25 | public class HostNameResolutionWithCustomHostResolverWithYAMLConfiguration { 26 | 27 | public static void main(String[] args) { 28 | try { 29 | execute(loadConfiguration("config.yml")); 30 | } catch (Throwable exc) { 31 | exc.printStackTrace(); 32 | } 33 | } 34 | 35 | public static Map loadConfiguration(String fileNameRelativePathFromClasspath) { 36 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); 37 | try (InputStream inputStream = ComponentContainer.getInstance().getPathHelper().getResourceAsStream(fileNameRelativePathFromClasspath)) { 38 | return mapper.readValue(inputStream, Map.class); 39 | } catch (IOException exc) { 40 | return Driver.throwException(exc); 41 | } 42 | } 43 | 44 | public static void execute(Map configuration) throws UnknownHostException, IOException { 45 | List resolvers = new ArrayList<>(); 46 | resolvers.add( 47 | new MappedHostResolver(() -> (List>)configuration.get("hostAliases")) 48 | ); 49 | resolvers.addAll( 50 | DNSJavaHostResolver.newInstances(() -> (List>)((Map)configuration.get("dns")).get("servers")) 51 | ); 52 | 53 | //This is the system default resolving wrapper 54 | resolvers.add(DefaultHostResolver.INSTANCE); 55 | 56 | //Installing the host resolvers 57 | HostResolutionRequestInterceptor.INSTANCE.install( 58 | resolvers.toArray(new HostResolver[resolvers.size()]) 59 | ); 60 | 61 | printHostInfo("my.hostname.one"); 62 | printHostInfo("my.hostname.two"); 63 | printHostInfo("my.hostname.three"); 64 | printHostInfo("my.hostname.four"); 65 | printHostInfo("google.com"); 66 | 67 | //Restoring hostname resolving to default and cleaning the cache 68 | HostResolutionRequestInterceptor.INSTANCE.uninstall(); 69 | 70 | //Now we have reset the hostnames in the map will not be resolved... 71 | printHostInfo("my.hostname.one"); 72 | printHostInfo("my.hostname.two"); 73 | printHostInfo("my.hostname.three"); 74 | printHostInfo("my.hostname.four"); 75 | //... Except this 76 | printHostInfo("google.com"); 77 | 78 | //Adding host aliases again 79 | HostResolutionRequestInterceptor.INSTANCE.install( 80 | resolvers.toArray(new HostResolver[resolvers.size()]) 81 | ); 82 | 83 | //Retesting 84 | printHostInfo("my.hostname.one"); 85 | printHostInfo("my.hostname.two"); 86 | printHostInfo("my.hostname.three"); 87 | printHostInfo("my.hostname.four"); 88 | printHostInfo("google.com"); 89 | } 90 | 91 | public static void printHostInfo(String hostname) { 92 | try { 93 | InetAddress inetAddress = InetAddress.getByName(hostname); 94 | ManagedLoggerRepository.logInfo(HostNameResolutionCustomizer.class::getName, "\n\n\tThe ip of hostname {} is {}\n\n", inetAddress.getHostName(), inetAddress.getHostAddress()); 95 | } catch (UnknownHostException exc) { 96 | ManagedLoggerRepository.logError(HostNameResolutionCustomizer.class::getName,"\n\n\tUnable to resolve hostname {}\n\n", hostname); 97 | } 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/java/com/github/jjbrt/dns/HostNameResolutionWithDNSClientHostResolverWithYAMLConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.dns; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Driver; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.net.InetAddress; 9 | import java.net.UnknownHostException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import org.burningwave.core.assembler.ComponentContainer; 15 | import org.burningwave.tools.net.DNSClientHostResolver; 16 | import org.burningwave.tools.net.DefaultHostResolver; 17 | import org.burningwave.tools.net.HostResolutionRequestInterceptor; 18 | import org.burningwave.tools.net.HostResolver; 19 | import org.burningwave.tools.net.MappedHostResolver; 20 | 21 | import com.fasterxml.jackson.databind.ObjectMapper; 22 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 23 | 24 | 25 | @SuppressWarnings("unchecked") 26 | public class HostNameResolutionWithDNSClientHostResolverWithYAMLConfiguration { 27 | 28 | public static void main(String[] args) { 29 | try { 30 | execute(loadConfiguration("config.yml")); 31 | } catch (Throwable exc) { 32 | exc.printStackTrace(); 33 | } 34 | } 35 | 36 | public static Map loadConfiguration(String fileNameRelativePathFromClasspath) { 37 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); 38 | try (InputStream inputStream = ComponentContainer.getInstance().getPathHelper().getResourceAsStream(fileNameRelativePathFromClasspath)) { 39 | return mapper.readValue(inputStream, Map.class); 40 | } catch (IOException exc) { 41 | return Driver.throwException(exc); 42 | } 43 | } 44 | 45 | public static void execute(Map configuration) throws UnknownHostException, IOException { 46 | List resolvers = new ArrayList<>(); 47 | 48 | resolvers.add( 49 | new MappedHostResolver(() -> (List>)configuration.get("hostAliases")) 50 | ); 51 | 52 | resolvers.addAll( 53 | DNSClientHostResolver.newInstances(() -> (List>)((Map)configuration.get("dns")).get("servers")) 54 | ); 55 | 56 | //This is the system default resolving wrapper 57 | resolvers.add(DefaultHostResolver.INSTANCE); 58 | 59 | //Installing the host resolvers 60 | HostResolutionRequestInterceptor.INSTANCE.install( 61 | resolvers.toArray(new HostResolver[resolvers.size()]) 62 | ); 63 | 64 | printHostInfo("my.hostname.one"); 65 | printHostInfo("my.hostname.two"); 66 | printHostInfo("my.hostname.three"); 67 | printHostInfo("my.hostname.four"); 68 | printHostInfo("google.com"); 69 | 70 | //Restoring hostname resolving to default and cleaning the cache 71 | HostResolutionRequestInterceptor.INSTANCE.uninstall(); 72 | 73 | //Now we have reset the hostnames in the map will not be resolved... 74 | printHostInfo("my.hostname.one"); 75 | printHostInfo("my.hostname.two"); 76 | printHostInfo("my.hostname.three"); 77 | printHostInfo("my.hostname.four"); 78 | //... Except this 79 | printHostInfo("google.com"); 80 | 81 | //Adding host aliases again 82 | HostResolutionRequestInterceptor.INSTANCE.install( 83 | resolvers.toArray(new HostResolver[resolvers.size()]) 84 | ); 85 | 86 | //Retesting 87 | printHostInfo("my.hostname.one"); 88 | printHostInfo("my.hostname.two"); 89 | printHostInfo("my.hostname.three"); 90 | printHostInfo("my.hostname.four"); 91 | printHostInfo("google.com"); 92 | } 93 | 94 | public static void printHostInfo(String hostname) { 95 | try { 96 | InetAddress inetAddress = InetAddress.getByName(hostname); 97 | ManagedLoggerRepository.logInfo(HostNameResolutionCustomizer.class::getName, "\n\n\tThe ip of hostname {} is {}\n\n", inetAddress.getHostName(), inetAddress.getHostAddress()); 98 | } catch (UnknownHostException exc) { 99 | ManagedLoggerRepository.logError(HostNameResolutionCustomizer.class::getName,"\n\n\tUnable to resolve hostname {}\n\n", hostname); 100 | } 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/resources/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | priority-of-this-configuration=3 2 | modules.export-all-to-all=false 3 | banner.hide=true 4 | managed-logger.repository.logging.info.disabled-for=\ 5 | org.burningwave.core.jvm.BufferHandler;\ 6 | org.burningwave.core.Cache;\ 7 | org.burningwave.core.assembler.ComponentContainer;\ 8 | org.burningwave.core.concurrent.QueuedTaskExecutor$Group$2;\ 9 | org.burningwave.core.assembler.StaticComponentContainer;\ 10 | org.burningwave.core.concurrent.TasksMonitorer -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | hostAliases: 2 | - ip: 123.123.123.123 3 | hostnames: 4 | - my.hostname.one 5 | - my.hostname.two 6 | - ip: 12.21.34.43 7 | hostnames: 8 | - my.hostname.three 9 | - my.hostname.four 10 | dns: 11 | servers: 12 | - ip: 208.67.222.222 13 | port: 53 14 | ipTypeToSearchFor: 15 | - IPV4 16 | - IPV6 17 | - ip: 208.67.222.220 18 | port: 53 19 | ipTypeToSearchFor: 20 | - IPV4 21 | - IPV6 -------------------------------------------------------------------------------- /customize-hostname-resolution/src/main/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 9 | 10 | 11 | 12 | 14 | ${LOGS_HOME}/web-core-error.log 15 | 16 | 17 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 18 | 19 | 20 | 21 | ERROR 22 | ACCEPT 23 | 26 | 27 | 28 | WARN 29 | DENY 30 | 31 | 32 | INFO 33 | DENY 34 | 35 | 36 | DEBUG 37 | DENY 38 | 39 | 40 | ${LOGS_HOME}/archived/web-core-error.%d{yyyy-MM-dd}.%i.log 41 | 43 | 25MB 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /dependency_injection/doc/class-diagram.drawio: -------------------------------------------------------------------------------- 1 | 7Vtdc6M2FP01flwP3x+PWSdNM53OZJppu9s3AsJmIywqcGz311cYCZAQxsZgs7uxZzLoSkhCOvecq2sy0xfx7hF7yep3FAA405RgN9PvZ5pmOw75mxv2hcFwlcKwxFFQmNTK8BL9B6iRNdtEAUi5hhlCMIsS3uij9Rr4GWfzMEZbvlmIID9q4i1Bw/Die7Bp/TsKslVhdTS7sv8KouWKjaxablETe6wxfZJ05QVoWzPpDzN9gRHKiqt4twAwXzu2LsV9v7TUlhPDYJ2dcgP8Z/fwm//8ZMSLt5e/Qv2Px9fHT1rRy7sHN/SBZ5oFSX+fX8nFMr9YwCgfgZpJ/2UNs4Uor1fSbE9Xzfp3g1jFp/Swp3ekgWomu6qy1osXJ+QCNks+9NK0NPHNuSmQaRWz4Gf2irstJ89el83+zxTgF4DfIx+QNptaSTbmne+jzTqrbvB4w7F5Nh5R42atYdJRAPLNVkn1KoshvQwjCBcIInxopwcecEKf2NMMozfAatZonY//DnAWEfjfwWi5JuYMJXQpqG+qNilvV1EGXhIvn/L9ljh+OaE6HilE8y7Brmai+HwEKAYZ3pMmrJb5CiUL1aTlbeV6JTOs6m6nUKNH3X1Z9l15BLmgTnGGgxjdDvK0/kaYB+HbuEiIvRhsEX7r5SYnY0gAgICp0PGB77cAA3qvAH5GOABYAFtR4/lvy8PAQq0UnyOgzFAkKFMkKHPHApktAZmwM2Ad3OVyRkoHUoz84xtElgfvv5CSMjdslRm+5tVzpSzf50uilKV9vfQMcEQeD2BqbF35FG2wD7p9KPPwEmTdYgQCTpKb+1jbJ1OyTcyGAfSy6J0Xctne0RGeUXRwUgoTTYCJrgrbXzw3vasuvGJHNt+RZgkdFQvT6OgApfKx+6PLaaWwy6TvqHBj4GXgFErqkOjWEaID6w5LekoLg9X8jCclQn3K4SPxwCGYyjF5CEqYypZ4gAiwwYiKucAlWBovCKyAU4vKnuIE9pO/DiQcF68uwQxDzW8NwgaATilqDDpaEzqqjD3Hw44qwc6FKpeXZb5YUz9T48RvUOXrVDTmLxORNF2MfPSekmY6HR21SBrZXG9fa5bkDdL2CRu2Ix2nwmHR46B6qbYfiqcgmIPK2TkR+DGxa3PEAZhMtwSsSZjMsZo+o41GZOb3IYJ8suEn1UGRqW6vg5oshhpLB3dR9oXJHrn+epBE26TFSgTzAqeBVDzP0c7W3eo8IKruqXpqTktPDYGazJ56ajmanOMG1lNTiAoNWzk+L9M81n4k/XU/9HdC+muIsZ51Y/3VZPhoJ1C6lhedIuo0WGPFc4mwm9/cafGbeF6we/KbYYsYMk/it6EoRZdp7tghG3kWgMPc8/vmLiYYr5n5t+kzxeeK+QxNkgq7bhyny/IZE8WU+LvjB6xYQCQQk+wXxyvDSpZ9GD1Ndi2BY0Q8FYFjTsxYpW9CTHd5HOknBvCDCZw+fdSUh9G5orATaHGn5R4/kJLCcDlZtuVTgaDmzt36x+AJyXbnZl9MOnOXP7+pjiL2NjYwZcmy0YF5XuKCAZPexmB5FJOt+OtOdijfKVcKyQ6972Hg5lxpTR+S/eGlT+sIaRnCT9iq0w81lmHM+a408YWMsXEje01niLxUFCcQxOCQuftJc0ws6mVb6zTD8KvmmPSxcpAfe20pwl7fOp9onPdiwhD5xPPEoNg29vq5eln0+4PKw3hBBSlWL+kXzav/dNAf/gc= -------------------------------------------------------------------------------- /dependency_injection/doc/class-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/dependency_injection/doc/class-diagram.png -------------------------------------------------------------------------------- /dependency_injection/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.github.jjbrt.java-tutorials 9 | dependency-injection 10 | 1.0.0-SNAPSHOT 11 | 12 | 13 | 1.8 14 | 1.8 15 | 16 | 17 | 18 | 19 | 20 | org.burningwave 21 | core 22 | 12.66.2 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/UserAccountApplication.java: -------------------------------------------------------------------------------- 1 | package com.useraccount; 2 | 3 | import org.di.framework.Injector; 4 | 5 | public class UserAccountApplication { 6 | 7 | public static void main(String[] args) { 8 | long startTime = System.currentTimeMillis(); 9 | Injector.startApplication(UserAccountApplication.class); 10 | Injector.getService(UserAccountClientComponent.class).displayUserAccount(); 11 | long endTime = System.currentTimeMillis(); 12 | System.out.println("\tElapsed time: " + getFormattedDifferenceOfMillis(endTime, startTime) + " seconds\n"); 13 | } 14 | 15 | static String getFormattedDifferenceOfMillis(long value1, long value2) { 16 | String valueFormatted = String.format("%04d", (value1 - value2)); 17 | return valueFormatted.substring(0, valueFormatted.length() - 3) + "," + valueFormatted.substring(valueFormatted.length() -3); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/UserAccountClientComponent.java: -------------------------------------------------------------------------------- 1 | package com.useraccount; 2 | 3 | import org.di.framework.annotations.Autowired; 4 | import org.di.framework.annotations.Component; 5 | import org.di.framework.annotations.Qualifier; 6 | 7 | import com.useraccount.services.AccountService; 8 | import com.useraccount.services.UserService; 9 | 10 | /** 11 | * Client class, havin userService and accountService expected to initialized by 12 | * CustomInjector.java 13 | */ 14 | @Component 15 | public class UserAccountClientComponent { 16 | 17 | @Autowired 18 | private UserService userService; 19 | 20 | @Autowired 21 | @Qualifier(value = "accountServiceImpl") 22 | private AccountService accountService; 23 | 24 | public void displayUserAccount() { 25 | String username = userService.getUserName(); 26 | Long accountNumber = accountService.getAccountNumber(username); 27 | System.out.println("\n\tUser Name: " + username + "\n\tAccount Number: " + accountNumber + "\n"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/services/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.useraccount.services; 2 | 3 | public interface AccountService { 4 | Long getAccountNumber(String userName); 5 | } 6 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/services/UserService.java: -------------------------------------------------------------------------------- 1 | package com.useraccount.services; 2 | 3 | public interface UserService { 4 | String getUserName(); 5 | } 6 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/services/impl/AccountServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.useraccount.services.impl; 2 | 3 | import org.di.framework.annotations.Component; 4 | 5 | import com.useraccount.services.AccountService; 6 | 7 | @Component 8 | public class AccountServiceImpl implements AccountService { 9 | 10 | @Override 11 | public Long getAccountNumber(String userName) { 12 | return 12345689L; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/com/useraccount/services/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.useraccount.services.impl; 2 | 3 | import org.di.framework.annotations.Component; 4 | 5 | import com.useraccount.services.UserService; 6 | 7 | @Component 8 | public class UserServiceImpl implements UserService { 9 | 10 | @Override 11 | public String getUserName() { 12 | return "username"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dependency_injection/src/main/java/org/di/framework/Injector.java: -------------------------------------------------------------------------------- 1 | package org.di.framework; 2 | 3 | import java.io.IOException; 4 | import java.util.Collection; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Map.Entry; 8 | import java.util.Optional; 9 | import java.util.Set; 10 | import java.util.stream.Collectors; 11 | 12 | import javax.management.RuntimeErrorException; 13 | 14 | import org.burningwave.core.assembler.ComponentContainer; 15 | import org.burningwave.core.classes.ClassCriteria; 16 | import org.burningwave.core.classes.ClassHunter; 17 | import org.burningwave.core.classes.SearchConfig; 18 | import org.di.framework.annotations.Component; 19 | import org.di.framework.utils.InjectionUtil; 20 | 21 | /** 22 | * Injector, to create objects for all @CustomService classes. autowire/inject 23 | * all dependencies 24 | */ 25 | public class Injector { 26 | private Map, Class> diMap; 27 | private Map, Object> applicationScope; 28 | 29 | private static Injector injector; 30 | 31 | private Injector() { 32 | super(); 33 | diMap = new HashMap<>(); 34 | applicationScope = new HashMap<>(); 35 | } 36 | 37 | /** 38 | * Start application 39 | * 40 | * @param mainClass 41 | */ 42 | public static void startApplication(Class mainClass) { 43 | try { 44 | synchronized (Injector.class) { 45 | if (injector == null) { 46 | injector = new Injector(); 47 | injector.initFramework(mainClass); 48 | } 49 | } 50 | } catch (Exception ex) { 51 | ex.printStackTrace(); 52 | } 53 | } 54 | 55 | public static T getService(Class classz) { 56 | try { 57 | return injector.getBeanInstance(classz); 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | return null; 62 | } 63 | 64 | /** 65 | * initialize the injector framework 66 | */ 67 | private void initFramework(Class mainClass) 68 | throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException { 69 | Class[] classes = getClasses(mainClass.getPackage().getName(), true); 70 | ComponentContainer componentConatiner = ComponentContainer.getInstance(); 71 | ClassHunter classHunter = componentConatiner.getClassHunter(); 72 | String packageRelPath = mainClass.getPackage().getName().replace(".", "/"); 73 | try (ClassHunter.SearchResult result = classHunter.findBy( 74 | SearchConfig.forResources( 75 | packageRelPath 76 | ).by(ClassCriteria.create().allThoseThatMatch(cls -> { 77 | return cls.getAnnotation(Component.class) != null; 78 | })) 79 | )) { 80 | Collection> types = result.getClasses(); 81 | for (Class implementationClass : types) { 82 | Class[] interfaces = implementationClass.getInterfaces(); 83 | if (interfaces.length == 0) { 84 | diMap.put(implementationClass, implementationClass); 85 | } else { 86 | for (Class iface : interfaces) { 87 | diMap.put(implementationClass, iface); 88 | } 89 | } 90 | } 91 | 92 | for (Class classz : classes) { 93 | if (classz.isAnnotationPresent(Component.class)) { 94 | Object classInstance = classz.newInstance(); 95 | applicationScope.put(classz, classInstance); 96 | InjectionUtil.autowire(this, classz, classInstance); 97 | } 98 | } 99 | }; 100 | 101 | } 102 | 103 | /** 104 | * Get all the classes for the input package 105 | */ 106 | public Class[] getClasses(String packageName, boolean recursive) throws ClassNotFoundException, IOException { 107 | ComponentContainer componentConatiner = ComponentContainer.getInstance(); 108 | ClassHunter classHunter = componentConatiner.getClassHunter(); 109 | String packageRelPath = packageName.replace(".", "/"); 110 | SearchConfig config = SearchConfig.forResources( 111 | packageRelPath 112 | ); 113 | if (!recursive) { 114 | config.findInChildren(); 115 | } 116 | 117 | try (ClassHunter.SearchResult result = classHunter.findBy(config)) { 118 | Collection> classes = result.getClasses(); 119 | return classes.toArray(new Class[classes.size()]); 120 | } 121 | } 122 | 123 | 124 | /** 125 | * Create and Get the Object instance of the implementation class for input 126 | * interface service 127 | */ 128 | @SuppressWarnings("unchecked") 129 | private T getBeanInstance(Class interfaceClass) throws InstantiationException, IllegalAccessException { 130 | return (T) getBeanInstance(interfaceClass, null, null); 131 | } 132 | 133 | /** 134 | * Overload getBeanInstance to handle qualifier and autowire by type 135 | */ 136 | public Object getBeanInstance(Class interfaceClass, String fieldName, String qualifier) 137 | throws InstantiationException, IllegalAccessException { 138 | Class implementationClass = getImplimentationClass(interfaceClass, fieldName, qualifier); 139 | 140 | if (applicationScope.containsKey(implementationClass)) { 141 | return applicationScope.get(implementationClass); 142 | } 143 | 144 | synchronized (applicationScope) { 145 | Object service = implementationClass.newInstance(); 146 | applicationScope.put(implementationClass, service); 147 | return service; 148 | } 149 | } 150 | 151 | /** 152 | * Get the name of the implimentation class for input interface service 153 | */ 154 | private Class getImplimentationClass(Class interfaceClass, final String fieldName, final String qualifier) { 155 | Set, Class>> implementationClasses = diMap.entrySet().stream() 156 | .filter(entry -> entry.getValue() == interfaceClass).collect(Collectors.toSet()); 157 | String errorMessage = ""; 158 | if (implementationClasses == null || implementationClasses.size() == 0) { 159 | errorMessage = "no implementation found for interface " + interfaceClass.getName(); 160 | } else if (implementationClasses.size() == 1) { 161 | Optional, Class>> optional = implementationClasses.stream().findFirst(); 162 | if (optional.isPresent()) { 163 | return optional.get().getKey(); 164 | } 165 | } else if (implementationClasses.size() > 1) { 166 | final String findBy = (qualifier == null || qualifier.trim().length() == 0) ? fieldName : qualifier; 167 | Optional, Class>> optional = implementationClasses.stream() 168 | .filter(entry -> entry.getKey().getSimpleName().equalsIgnoreCase(findBy)).findAny(); 169 | if (optional.isPresent()) { 170 | return optional.get().getKey(); 171 | } else { 172 | errorMessage = "There are " + implementationClasses.size() + " of interface " + interfaceClass.getName() 173 | + " Expected single implementation or make use of @CustomQualifier to resolve conflict"; 174 | } 175 | } 176 | throw new RuntimeErrorException(new Error(errorMessage)); 177 | } 178 | } -------------------------------------------------------------------------------- /dependency_injection/src/main/java/org/di/framework/annotations/Autowired.java: -------------------------------------------------------------------------------- 1 | package org.di.framework.annotations; 2 | 3 | import static java.lang.annotation.ElementType.CONSTRUCTOR; 4 | import static java.lang.annotation.ElementType.FIELD; 5 | import static java.lang.annotation.ElementType.METHOD; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.Target; 11 | 12 | /** 13 | * Service field variables should use this annotation 14 | */ 15 | @Target({ METHOD, CONSTRUCTOR, FIELD }) 16 | @Retention(RUNTIME) 17 | @Documented 18 | public @interface Autowired { 19 | 20 | } -------------------------------------------------------------------------------- /dependency_injection/src/main/java/org/di/framework/annotations/Component.java: -------------------------------------------------------------------------------- 1 | package org.di.framework.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Client class should use this annotation 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.TYPE) 13 | public @interface Component { 14 | 15 | } -------------------------------------------------------------------------------- /dependency_injection/src/main/java/org/di/framework/annotations/Qualifier.java: -------------------------------------------------------------------------------- 1 | package org.di.framework.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Service field variables should use this annotation 7 | * This annotation Can be used to avoid conflict if there are multiple implementations of the same interface 8 | */ 9 | @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Inherited 12 | @Documented 13 | public @interface Qualifier { 14 | String value() default ""; 15 | } -------------------------------------------------------------------------------- /dependency_injection/src/main/java/org/di/framework/utils/InjectionUtil.java: -------------------------------------------------------------------------------- 1 | package org.di.framework.utils; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Fields; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.Collection; 7 | 8 | import org.burningwave.core.classes.FieldCriteria; 9 | import org.di.framework.Injector; 10 | import org.di.framework.annotations.Autowired; 11 | import org.di.framework.annotations.Qualifier; 12 | 13 | public class InjectionUtil { 14 | 15 | private InjectionUtil() { 16 | super(); 17 | } 18 | 19 | /** 20 | * Perform injection recursively, for each service inside the Client class 21 | */ 22 | public static void autowire(Injector injector, Class classz, Object classInstance) 23 | throws InstantiationException, IllegalAccessException { 24 | Collection fields = Fields.findAllAndMakeThemAccessible( 25 | FieldCriteria.forEntireClassHierarchy().allThoseThatMatch(field -> 26 | field.isAnnotationPresent(Autowired.class) 27 | ), 28 | classz 29 | ); 30 | for (Field field : fields) { 31 | String qualifier = field.isAnnotationPresent(Qualifier.class) 32 | ? field.getAnnotation(Qualifier.class).value() 33 | : null; 34 | Object fieldInstance = injector.getBeanInstance(field.getType(), field.getName(), qualifier); 35 | Fields.setDirect(classInstance, field, fieldInstance); 36 | autowire(injector, fieldInstance.getClass(), fieldInstance); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /docs/Java-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/Java-logo.png -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% seo %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 26 | 27 |
28 | {{ content }} 29 | 30 | 35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "{{ site.theme }}"; 5 | .page-header { 6 | background-image: linear-gradient(120deg, #535355, #e46825); 7 | } 8 | 9 | h1.project-name { 10 | font-family: 'Tomcat Bold'; 11 | font-size: 4.25em; 12 | font-style: italic; 13 | line-height: 1.00em; 14 | } 15 | 16 | @font-face { 17 | font-family: 'Tomcat Bold'; 18 | src: url('Tomcat-Bold.eot'); 19 | src: local('Tomcat Bold'), local('Tomcat-Bold'), 20 | url('./../fonts/Tomcat-Bold.eot?#iefix') format('embedded-opentype'), 21 | url('./../fonts/Tomcat-Bold.woff2') format('woff2'), 22 | url('./../fonts/Tomcat-Bold.woff') format('woff'), 23 | url('./../fonts/Tomcat-Bold.ttf') format('truetype'); 24 | font-weight: bold; 25 | font-style: normal; 26 | font-display: swap; 27 | } 28 | 29 | @font-face { 30 | font-family: 'Tomcat Regular'; 31 | src: url('Tomcat-Regular.eot'); 32 | src: local('Tomcat'), local('Tomcat-Regular'), 33 | url('./../fonts/Tomcat-Regular.eot?#iefix') format('embedded-opentype'), 34 | url('./../fonts/Tomcat-Regular.woff2') format('woff2'), 35 | url('./../fonts/Tomcat-Regular.woff') format('woff'), 36 | url('./../fonts/Tomcat-Regular.ttf') format('truetype'); 37 | font-weight: normal; 38 | font-style: normal; 39 | font-display: swap; 40 | } 41 | -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Bold.eot -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Bold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Bold.woff -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Bold.woff2 -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Regular.eot -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Regular.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Regular.woff -------------------------------------------------------------------------------- /docs/assets/fonts/Tomcat-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JJBRT/advanced-java-tutorials/83dfdecd03237e1a302da608d8d392629a2d9cc4/docs/assets/fonts/Tomcat-Regular.woff2 -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Advanced Java tutorials 2 | 3 | Java-logo.png 4 | 5 | 6 | A collection of examples about advanced Java programming. Here you will find tutorials about: 7 | 8 | * [how to create your own dependency injection framework](https://jim-jerald-burton.medium.com/how-to-create-your-own-dependency-injection-framework-in-java-12a6e52aeff9) 9 | * [how to make applications created with old Java versions work on Java 9 and later versions](https://dev.to/bw_software/making-applications-created-with-old-java-versions-work-on-java-9-and-later-versions-19ld) 10 | * [how to make reflection fully work on Java 9 and later](https://jim-jerald-burton.medium.com/making-reflection-fully-work-on-java-9-and-later-767320344d1d) 11 | * [how to export all modules to all modules at runtime on Java 9 and later](https://jim-jerald-burton.medium.com/exporting-all-modules-to-all-modules-at-runtime-on-java-9-and-later-3517eb479701) 12 | * [how to iterate collections and arrays in parallel by setting thread priority](https://dev.to/bw_software/iterating-collections-and-arrays-in-parallel-5acg) 13 | * [how to configure host name resolution to use a universal custom host name resolver](https://dev.to/jjbrt/how-to-configure-hostname-resolution-to-use-a-universal-custom-hostname-resolver-in-java-14p0) 14 | * [how to query and validate a JSON document](https://dev.to/jjbrt/querying-and-validating-a-json-document-in-java-323i) 15 | 16 |
17 | 18 | **Any instructions to make each project work are indicated in the possible README.md file inside it**. 19 | -------------------------------------------------------------------------------- /json/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.github.jjbrt.java-tutorials 9 | json 10 | 1.0.0-SNAPSHOT 11 | 12 | 13 | 16 14 | 16 15 | 16 | 17 | 18 | 19 | 20 | org.burningwave 21 | json 22 | 0.13.1 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/ObjectHandlerExample.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json; 2 | 3 | import java.util.Map; 4 | 5 | import org.burningwave.json.Facade; 6 | import org.burningwave.json.ObjectHandler; 7 | import org.burningwave.json.Path; 8 | 9 | import com.github.jjbrt.json.bean.Question; 10 | import com.github.jjbrt.json.bean.Root; 11 | import com.github.jjbrt.json.bean.Sport; 12 | 13 | 14 | class ObjectHandlerExample { 15 | static final Facade facade = Facade.create(); 16 | 17 | public static void main(String[] args) { 18 | try { 19 | findFirstWithFinder(); 20 | findFirstWithValueFinder(); 21 | findFirstWithValueAndConvert(); 22 | } catch (Throwable exc) { 23 | exc.printStackTrace(); 24 | } 25 | } 26 | 27 | static void findFirstWithFinder() { 28 | //Loading the JSON object 29 | ObjectHandler objectHandler = facade.newObjectHandler( 30 | ObjectHandlerExample.class.getClassLoader().getResourceAsStream("quiz.json"), 31 | Root.class 32 | ); 33 | 34 | ObjectHandler.Finder finder = objectHandler.newFinder(); 35 | ObjectHandler sportOH = finder.findFirstForPathEndsWith("sport"); 36 | //Retrieving the path of the sport object ("quiz.sport") 37 | String sportPath = sportOH.getPath(); 38 | //Retrieving the value of the sport object 39 | Sport sport = sportOH.getValue(); 40 | ObjectHandler option2OfSportQuestionOH = finder.findFirstForPathEndsWith(Path.of("sport", "q1", "options[1]")); 41 | String option2OfSportQuestionOHPath = option2OfSportQuestionOH.getPath(); 42 | String option2OfSportQuestion = option2OfSportQuestionOH.getValue(); 43 | ObjectHandler questionOneOH = finder.findForPathEquals(Path.of("quiz", "sport", "q1")); 44 | String questionOnePath = questionOneOH.getPath(); 45 | Question questionOne = questionOneOH.getValue(); 46 | } 47 | 48 | static void findFirstWithValueFinder() { 49 | //Loading the JSON object 50 | ObjectHandler objectHandler = facade.newObjectHandler( 51 | ObjectHandlerExample.class.getClassLoader().getResourceAsStream("quiz.json"), 52 | Root.class 53 | ); 54 | 55 | ObjectHandler.ValueFinder finder = objectHandler.newValueFinder(); 56 | Sport sport = finder.findFirstForPathEndsWith("sport"); 57 | String option2OfSportQuestion = finder.findFirstForPathEndsWith(Path.of("sport", "q1", "options[1]")); 58 | Question questionOne = finder.findForPathEquals(Path.of("quiz", "sport", "q1")); 59 | } 60 | 61 | static void findFirstWithValueAndConvert() { 62 | //Loading the JSON object 63 | ObjectHandler objectHandler = facade.newObjectHandler( 64 | ObjectHandlerExample.class.getClassLoader().getResourceAsStream("quiz.json"), 65 | Root.class 66 | ); 67 | 68 | ObjectHandler.ValueFinderAndConverter finderAndConverter = objectHandler.newValueFinderAndConverter(Map.class); 69 | Map sportAsMap = finderAndConverter.findFirstForPathEndsWith("sport"); 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/ValidatorExample.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json; 2 | 3 | import java.util.Collection; 4 | 5 | import org.burningwave.json.Check; 6 | import org.burningwave.json.Facade; 7 | import org.burningwave.json.ObjectHandler; 8 | import org.burningwave.json.Validation; 9 | 10 | import com.github.jjbrt.json.bean.Root; 11 | 12 | public class ValidatorExample { 13 | 14 | static final Facade facade = Facade.create(); 15 | 16 | public static void main(String[] args) { 17 | try { 18 | validate(); 19 | } catch (Throwable exc) { 20 | exc.printStackTrace(); 21 | } 22 | } 23 | 24 | static void validate() { 25 | facade.validator().registerCheck( 26 | //Checking whether a value in any field marked as required (e.g.: @JsonProperty(value = "answer", required = true)) is null 27 | Check.forAll().checkMandatory(), 28 | //Checking whether a string value in any field is empty 29 | Check.forAllStringValues().execute(pathValidationContext -> { 30 | if (pathValidationContext.getValue() != null && pathValidationContext.getValue().trim().equals("")) { 31 | pathValidationContext.rejectValue("IS_EMPTY", "is empty"); 32 | } 33 | }) 34 | ); 35 | 36 | //Loading the JSON object 37 | ObjectHandler objectHandler = facade.newObjectHandler( 38 | ValidatorExample.class.getClassLoader().getResourceAsStream("quiz.json"), 39 | Root.class 40 | ); 41 | Collection exceptions = facade.validator().validate( 42 | Validation.Config.forJsonObject(objectHandler.getValue()) 43 | //By calling this method the validation will be performed on the entire document, 44 | //otherwise the validation will stop at the first exception thrown 45 | .withCompleteValidation() 46 | ); 47 | for (Throwable exc : exceptions) { 48 | System.err.println(exc.getMessage()); 49 | }; 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/bean/Maths.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json.bean; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class Maths { 6 | Question q1; 7 | Question q2; 8 | 9 | @JsonProperty("q1") 10 | public Question getQ1() { 11 | return this.q1; 12 | } 13 | 14 | @JsonProperty("q2") 15 | public Question getQ2() { 16 | return this.q2; 17 | } 18 | 19 | public void setQ1(Question q1) { 20 | this.q1 = q1; 21 | } 22 | 23 | public void setQ2(Question q2) { 24 | this.q2 = q2; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/bean/Question.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | 8 | public class Question { 9 | String answer; 10 | List options; 11 | String text; 12 | 13 | @JsonProperty(value = "answer", required = true) 14 | public String getAnswer() { 15 | return this.answer; 16 | } 17 | 18 | @JsonProperty(value = "options", required = true) 19 | public List getOptions() { 20 | return this.options; 21 | } 22 | 23 | @JsonProperty(value = "text", required = true) 24 | public String getQuestion() { 25 | return this.text; 26 | } 27 | 28 | public void setAnswer(String answer) { 29 | this.answer = answer; 30 | } 31 | 32 | public void setOptions(ArrayList options) { 33 | this.options = options; 34 | } 35 | 36 | public void setQuestion(String question) { 37 | this.text = question; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/bean/Quiz.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json.bean; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class Quiz { 6 | Maths maths; 7 | 8 | Sport sport; 9 | 10 | @JsonProperty("maths") 11 | public Maths getMaths() { 12 | return this.maths; 13 | } 14 | 15 | @JsonProperty("sport") 16 | public Sport getSport() { 17 | return this.sport; 18 | } 19 | 20 | public void setMaths(Maths maths) { 21 | this.maths = maths; 22 | } 23 | 24 | public void setSport(Sport sport) { 25 | this.sport = sport; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/bean/Root.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json.bean; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class Root{ 6 | Quiz quiz; 7 | @JsonProperty("quiz") 8 | public Quiz getQuiz() { 9 | return this.quiz; } 10 | 11 | public void setQuiz(Quiz quiz) { 12 | this.quiz = quiz; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /json/src/main/java/com/github/jjbrt/json/bean/Sport.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.json.bean; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class Sport { 6 | Question q1; 7 | 8 | @JsonProperty("q1") 9 | public Question getQ1() { 10 | return this.q1; 11 | } 12 | 13 | public void setQ1(Question q1) { 14 | this.q1 = q1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /json/src/main/resources/quiz-to-be-validated.json: -------------------------------------------------------------------------------- 1 | { 2 | "quiz": { 3 | "sport": { 4 | "q1": { 5 | "text": "Which one is correct team name in NBA?", 6 | "options": [ 7 | "New York Bulls", 8 | "Los Angeles Kings", 9 | "Golden State Warriros", 10 | "Huston Rocket" 11 | ], 12 | "answer": "Huston Rocket" 13 | } 14 | }, 15 | "maths": { 16 | "q1": { 17 | "text": "5 + 7 = ?", 18 | "options": [ 19 | "10", 20 | "11", 21 | "12", 22 | "13" 23 | ] 24 | }, 25 | "q2": { 26 | "options": [ 27 | "1", 28 | "2", 29 | "3", 30 | "" 31 | ], 32 | "answer": "4" 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /json/src/main/resources/quiz.json: -------------------------------------------------------------------------------- 1 | { 2 | "quiz": { 3 | "sport": { 4 | "q1": { 5 | "text": "Which one is correct team name in NBA?", 6 | "options": [ 7 | "New York Bulls", 8 | "Los Angeles Kings", 9 | "Golden State Warriros", 10 | "Huston Rocket" 11 | ], 12 | "answer": "Huston Rocket" 13 | } 14 | }, 15 | "maths": { 16 | "q1": { 17 | "text": "5 + 7 = ?", 18 | "options": [ 19 | "10", 20 | "11", 21 | "12", 22 | "13" 23 | ], 24 | "answer": "12" 25 | }, 26 | "q2": { 27 | "text": "12 - 8 = ?", 28 | "options": [ 29 | "1", 30 | "2", 31 | "3", 32 | "4" 33 | ], 34 | "answer": "4" 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /parallel-iteration/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.github.jjbrt.java-tutorials 9 | parallel-iteration 10 | 1.0.0-SNAPSHOT 11 | 12 | 13 | 17 14 | 17 15 | 16 | 17 | 18 | 19 | 20 | org.burningwave 21 | core 22 | 12.66.2 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /parallel-iteration/src/main/java/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | priority-of-this-configuration=1 2 | banner.hide=true 3 | #jvm.driver=io.github.toolfactory.jvm.DefaultDriver 4 | jvm.driver=org.burningwave.jvm.DynamicDriver 5 | #jvm.driver=org.burningwave.jvm.NativeDriver 6 | managed-logger.repository.enabled=true -------------------------------------------------------------------------------- /parallel-iteration/src/main/java/com/github/jjbrt/iteration/ArraysIterator.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.iteration; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.IterableObjectHelper; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.burningwave.core.iterable.IterableObjectHelper.IterationConfig; 10 | 11 | public class ArraysIterator { 12 | 13 | public static void main(String[] args) { 14 | try { 15 | iterate(buildInputCollection()); 16 | } catch (Throwable exc) { 17 | exc.printStackTrace(); 18 | } 19 | } 20 | 21 | 22 | 23 | private static Object[] buildInputCollection() { 24 | Object[] input = new Object[100000000]; 25 | for (int i = 0; i < input.length; i++) { 26 | input[i] = Integer.valueOf(i + 1); 27 | } 28 | return input; 29 | } 30 | 31 | 32 | 33 | private static void iterate(Object[] inputCollection) { 34 | long initialTime = System.currentTimeMillis(); 35 | List outputCollection = IterableObjectHelper.createIterateAndGetTask( 36 | IterationConfig.of(inputCollection) 37 | .parallelIf(inputColl -> inputColl.length > 2) 38 | .withOutput(new ArrayList()) 39 | .withAction((number, outputCollectionSupplier) -> { 40 | int intNumber = (int)number; 41 | if ((int)number <= inputCollection.length - 10) { 42 | //Skipping iterated item 43 | return; 44 | } 45 | if (((int)number % 2) == 0) { 46 | outputCollectionSupplier.accept(outputColl -> 47 | outputColl.add((Long.valueOf(intNumber) * intNumber)) 48 | ); 49 | } 50 | }) 51 | 52 | ).submit().join(); 53 | IterableObjectHelper.iterate( 54 | IterationConfig.of(outputCollection) 55 | //Disabling parallel iteration 56 | .parallelIf(inputColl -> false) 57 | .withAction((number) -> { 58 | ManagedLoggerRepository.logInfo(ArraysIterator.class::getName, "Iterated number: {}", number); 59 | }) 60 | ); 61 | 62 | ManagedLoggerRepository.logInfo( 63 | ListsIterator.class::getName, 64 | "\n\n\tInput collection size: {}\n\tOutput collection size: {}\n\tTotal elapsed time: {}s\n", 65 | inputCollection.length, 66 | outputCollection.size(), 67 | getFormattedDifferenceOfMillis(System.currentTimeMillis(),initialTime) 68 | ); 69 | } 70 | 71 | 72 | private static String getFormattedDifferenceOfMillis(long value1, long value2) { 73 | String valueFormatted = String.format("%04d", (value1 - value2)); 74 | return valueFormatted.substring(0, valueFormatted.length() - 3) + "," + valueFormatted.substring(valueFormatted.length() -3); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /parallel-iteration/src/main/java/com/github/jjbrt/iteration/ListsIterator.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.iteration; 2 | 3 | 4 | import static org.burningwave.core.assembler.StaticComponentContainer.IterableObjectHelper; 5 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collection; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | import java.util.stream.IntStream; 12 | 13 | import org.burningwave.core.iterable.IterableObjectHelper.IterationConfig; 14 | 15 | 16 | public class ListsIterator { 17 | 18 | public static void main(String[] args) { 19 | try { 20 | iterate(buildInputCollection()); 21 | } catch (Throwable exc) { 22 | exc.printStackTrace(); 23 | } 24 | } 25 | 26 | 27 | 28 | private static Collection buildInputCollection() { 29 | return IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList()); 30 | } 31 | 32 | 33 | 34 | private static void iterate(Collection inputCollection) { 35 | long initialTime = System.currentTimeMillis(); 36 | List outputCollection = IterableObjectHelper.createIterateAndGetTask( 37 | IterationConfig.of(inputCollection) 38 | .parallelIf(inputColl -> inputColl.size() > 2) 39 | .withOutput(new ArrayList()) 40 | .withAction((number, outputCollectionSupplier) -> { 41 | if (number > inputCollection.size() / 2) { 42 | //Terminating the current thread iteration early. 43 | IterableObjectHelper.terminateCurrentThreadIteration(); 44 | //If we need to terminate all threads iteration (useful for a find first iteration) we must use 45 | //IterableObjectHelper.terminateIteration(); 46 | } 47 | if ((number % 2) == 0) { 48 | outputCollectionSupplier.accept(outputColl -> 49 | outputColl.add(number) 50 | ); 51 | } 52 | }) 53 | 54 | ).submit().join(); 55 | ManagedLoggerRepository.logInfo( 56 | ListsIterator.class::getName, 57 | "\n\n\tInput collection size: {}\n\tOutput collection size: {}\n\tTotal elapsed time: {}s\n", 58 | inputCollection.size(), 59 | outputCollection.size(), 60 | getFormattedDifferenceOfMillis(System.currentTimeMillis(),initialTime) 61 | ); 62 | } 63 | 64 | private static String getFormattedDifferenceOfMillis(long value1, long value2) { 65 | String valueFormatted = String.format("%04d", (value1 - value2)); 66 | return valueFormatted.substring(0, valueFormatted.length() - 3) + "," + valueFormatted.substring(valueFormatted.length() -3); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /reflection/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.github.jjbrt.java-tutorials 9 | reflection 10 | 1.0.0-SNAPSHOT 11 | 12 | 13 | 16 14 | 16 15 | 16 | 17 | 18 | 19 | 20 | org.burningwave 21 | core 22 | 12.66.2 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /reflection/src/main/java/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | priority-of-this-configuration=1 2 | banner.hide=false 3 | #jvm.driver=io.github.toolfactory.jvm.DefaultDriver 4 | jvm.driver=org.burningwave.jvm.DynamicDriver 5 | #jvm.driver=org.burningwave.jvm.NativeDriver 6 | managed-logger.repository.enabled=false 7 | #avoiding the automatic call on startup of Burningwave Core to method 8 | #org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll() 9 | #which exports all modules to all modules 10 | modules.export-all-to-all=false 11 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/AllModulesToAllModulesExporter.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Modules; 5 | 6 | import java.lang.reflect.Constructor; 7 | import java.lang.reflect.Method; 8 | 9 | 10 | @SuppressWarnings("unchecked") 11 | public class AllModulesToAllModulesExporter { 12 | 13 | public static void main(String[] args) { 14 | try { 15 | execute(); 16 | } catch (Throwable exc) { 17 | exc.printStackTrace(); 18 | } 19 | } 20 | 21 | 22 | public static void execute() { 23 | try { 24 | Modules.exportAllToAll(); 25 | Class bootClassLoaderClass = Class.forName("jdk.internal.loader.ClassLoaders$BootClassLoader"); 26 | Constructor constructor = 27 | (Constructor) 28 | Class.forName("jdk.internal.loader.ClassLoaders$PlatformClassLoader") 29 | .getDeclaredConstructor(bootClassLoaderClass); 30 | constructor.setAccessible(true); 31 | Class classLoadersClass = Class.forName("jdk.internal.loader.ClassLoaders"); 32 | Method bootClassLoaderRetriever = classLoadersClass.getDeclaredMethod("bootLoader"); 33 | bootClassLoaderRetriever.setAccessible(true); 34 | ClassLoader newBuiltinclassLoader = constructor.newInstance(bootClassLoaderRetriever.invoke(classLoadersClass)); 35 | System.out.println(newBuiltinclassLoader + " instantiated"); 36 | } catch (Exception exc) { 37 | exc.printStackTrace(); 38 | } 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/FieldsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.Collection; 5 | import java.util.Map; 6 | 7 | 8 | public class FieldsHandler { 9 | 10 | 11 | public static void main(String[] args) { 12 | try { 13 | execute(); 14 | } catch (Throwable exc) { 15 | exc.printStackTrace(); 16 | } 17 | } 18 | 19 | 20 | public static void execute() { 21 | org.burningwave.core.classes.Fields fields = 22 | org.burningwave.core.assembler.StaticComponentContainer.Fields; 23 | 24 | ClassLoader classLoader = 25 | Thread.currentThread().getContextClassLoader(); 26 | 27 | //Fast access by memory address 28 | Collection> loadedClasses = 29 | fields.getDirect(classLoader, "classes"); 30 | 31 | loadedClasses.forEach((cls) -> { 32 | System.out.println(cls.getName()); 33 | }); 34 | 35 | //Access by Reflection 36 | loadedClasses = fields.get(classLoader, "classes"); 37 | 38 | //Get all field values of an object 39 | //through memory address access 40 | Map values = 41 | fields.getAllDirect(classLoader); 42 | 43 | //Get all field values of an object 44 | //through reflection access 45 | values = fields.getAll(classLoader); 46 | 47 | values.forEach((name, value) -> { 48 | System.out.println(name + " =\n\t\t " + value); 49 | }); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/MethodHandleInvoker.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Resources; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Methods; 5 | import org.burningwave.core.io.FileSystemItem; 6 | 7 | public class MethodHandleInvoker { 8 | 9 | 10 | public static void main(String[] args) { 11 | try { 12 | execute(); 13 | } catch (Throwable exc) { 14 | exc.printStackTrace(); 15 | } 16 | } 17 | 18 | 19 | public static void execute() { 20 | //loading the byte code 21 | FileSystemItem currentPath = Resources.get(MethodHandleInvoker.class).getParent(); 22 | FileSystemItem fieldsHandlerClassFile = currentPath.findFirstInChildren( 23 | FileSystemItem.Criteria.forAllFileThat( 24 | fileSystemItem -> fileSystemItem.getName().equals("FieldsHandler.class") 25 | ) 26 | ); 27 | 28 | byte[] byteCode = fieldsHandlerClassFile.toByteArray(); 29 | 30 | //Calling defineClass method 31 | Class fieldsHandlerClass = Methods.invokeDirect( 32 | Thread.currentThread().getContextClassLoader(), 33 | "defineClass", 34 | "com.github.jjbrt.reflection.FieldsHandler", 35 | byteCode, 36 | 0, 37 | byteCode.length, 38 | null 39 | ); 40 | 41 | //Calling execute method of com.github.jjbrt.reflection.FieldsHandler class 42 | Methods.invokeStatic(fieldsHandlerClass, "execute"); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/MethodHandleRetrieverAndInvoker.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Methods; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Resources; 5 | 6 | import java.lang.invoke.MethodHandle; 7 | import java.security.ProtectionDomain; 8 | 9 | import org.burningwave.core.classes.MethodCriteria; 10 | import org.burningwave.core.io.FileSystemItem; 11 | 12 | public class MethodHandleRetrieverAndInvoker { 13 | 14 | 15 | 16 | public static void main(String[] args) { 17 | try { 18 | execute(); 19 | } catch (Throwable exc) { 20 | exc.printStackTrace(); 21 | } 22 | } 23 | 24 | 25 | public static void execute() throws Throwable { 26 | //Filtering and obtaining a MethodHandle reference 27 | MethodHandle defineClassMethodHandle = Methods.findOneDirectHandle( 28 | MethodCriteria.byScanUpTo((cls) -> 29 | //We analyze all the classes between Thread.currentThread().getContextClassLoader().getClass() and 30 | //ClassLoader class and not all of its hierarchy (default behavior) 31 | cls.getName().equals(ClassLoader.class.getName()) 32 | ).name( 33 | "defineClass"::equals 34 | ).and().parameterTypes(params -> 35 | params.length == 5 36 | ).and().parameterTypesAreAssignableFrom( 37 | String.class, byte[].class, int.class, int.class, ProtectionDomain.class 38 | ).and().returnType((cls) -> 39 | cls.getName().equals(Class.class.getName()) 40 | ), 41 | Thread.currentThread().getContextClassLoader().getClass() 42 | ); 43 | 44 | //loading the byte code 45 | FileSystemItem currentPath = Resources.get(MethodHandleRetrieverAndInvoker.class).getParent(); 46 | FileSystemItem fieldsHandlerClassFile = currentPath.findFirstInChildren( 47 | FileSystemItem.Criteria.forAllFileThat( 48 | fileSystemItem -> fileSystemItem.getName().equals("FieldsHandler.class") 49 | ) 50 | ); 51 | byte[] byteCode = fieldsHandlerClassFile.toByteArray(); 52 | 53 | //invoking defineClass method 54 | Class fieldsHandlerClass = (Class) defineClassMethodHandle.invoke( 55 | Thread.currentThread().getContextClassLoader(), 56 | "com.github.jjbrt.reflection.FieldsHandler", 57 | byteCode, 58 | 0, 59 | byteCode.length, 60 | null 61 | ); 62 | 63 | //Obtaining execute MethodHandle reference 64 | MethodHandle executeMethodHandle = Methods.findOneDirectHandle( 65 | MethodCriteria.byScanUpTo((cls) -> 66 | //We only analyze the com.github.jjbrt.reflection.FieldsHandler class and not all of its hierarchy (default behavior) 67 | cls.getName().equals(fieldsHandlerClass.getName()) 68 | ).name( 69 | "execute"::equals 70 | ).and().parameterTypes(params -> 71 | params.length == 0 72 | ), 73 | fieldsHandlerClass 74 | ); 75 | 76 | //Calling execute method of com.github.jjbrt.reflection.FieldsHandler class 77 | executeMethodHandle.invoke(); 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/MethodInvoker.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Resources; 5 | import static org.burningwave.core.assembler.StaticComponentContainer.Methods; 6 | import org.burningwave.core.io.FileSystemItem; 7 | 8 | public class MethodInvoker { 9 | 10 | 11 | public static void main(String[] args) { 12 | try { 13 | execute(); 14 | } catch (Throwable exc) { 15 | exc.printStackTrace(); 16 | } 17 | } 18 | 19 | 20 | public static void execute() { 21 | //loading the byte code 22 | FileSystemItem currentPath = Resources.get(MethodInvoker.class).getParent(); 23 | FileSystemItem fieldsHandlerClassFile = currentPath.findFirstInChildren( 24 | FileSystemItem.Criteria.forAllFileThat( 25 | fileSystemItem -> fileSystemItem.getName().equals("FieldsHandler.class") 26 | ) 27 | ); 28 | 29 | byte[] byteCode = fieldsHandlerClassFile.toByteArray(); 30 | 31 | //Calling define method 32 | Class fieldsHandlerClass = Methods.invokeDirect( 33 | Thread.currentThread().getContextClassLoader(), 34 | "defineClass", 35 | "com.github.jjbrt.reflection.FieldsHandler", 36 | byteCode, 37 | 0, 38 | byteCode.length, 39 | null 40 | ); 41 | 42 | //Calling execute method of com.github.jjbrt.reflection.FieldsHandler class 43 | Methods.invokeStaticDirect(fieldsHandlerClass, "execute"); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/MethodRetrieverAndInvoker.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Resources; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Methods; 5 | 6 | import java.lang.reflect.Method; 7 | import java.security.ProtectionDomain; 8 | 9 | import org.burningwave.core.classes.MethodCriteria; 10 | import org.burningwave.core.io.FileSystemItem; 11 | 12 | public class MethodRetrieverAndInvoker { 13 | 14 | 15 | public static void main(String[] args) { 16 | try { 17 | execute(); 18 | } catch (Throwable exc) { 19 | exc.printStackTrace(); 20 | } 21 | } 22 | 23 | 24 | public static void execute() { 25 | //Filtering and obtaining a Method reference 26 | Method defineClassMethod = Methods.findFirst( 27 | MethodCriteria.byScanUpTo((cls) -> 28 | //We analyze all the classes between Thread.currentThread().getContextClassLoader().getClass() and 29 | //ClassLoader class and not all of its hierarchy (default behavior) 30 | cls.getName().equals(ClassLoader.class.getName()) 31 | ).name( 32 | "defineClass"::equals 33 | ).and().parameterTypes(params -> 34 | params.length == 5 35 | ).and().parameterTypesAreAssignableFrom( 36 | String.class, byte[].class, int.class, int.class, ProtectionDomain.class 37 | ).and().returnType((cls) -> 38 | cls.getName().equals(Class.class.getName()) 39 | ), 40 | Thread.currentThread().getContextClassLoader().getClass() 41 | ); 42 | 43 | //loading the byte code 44 | FileSystemItem currentPath = Resources.get(MethodRetrieverAndInvoker.class).getParent(); 45 | FileSystemItem fieldsHandlerClassFile = currentPath.findFirstInChildren( 46 | FileSystemItem.Criteria.forAllFileThat( 47 | fileSystemItem -> fileSystemItem.getName().equals("FieldsHandler.class") 48 | ) 49 | ); 50 | byte[] byteCode = fieldsHandlerClassFile.toByteArray(); 51 | 52 | //invoking defineClass method 53 | Class fieldsHandlerClass = Methods.invoke( 54 | Thread.currentThread().getContextClassLoader(), 55 | defineClassMethod, 56 | "com.github.jjbrt.reflection.FieldsHandler", 57 | byteCode, 58 | 0, 59 | byteCode.length, 60 | null 61 | ); 62 | 63 | //Obtaining execute Method reference 64 | Method executeMethod = Methods.findOne( 65 | MethodCriteria.byScanUpTo((cls) -> 66 | //We only analyze the com.github.jjbrt.reflection.FieldsHandler class and not all of its hierarchy (default behavior) 67 | cls.getName().equals(fieldsHandlerClass.getName()) 68 | ).name( 69 | "execute"::equals 70 | ).and().parameterTypes(params -> 71 | params.length == 0 72 | ), 73 | fieldsHandlerClass 74 | ); 75 | 76 | //Calling execute method of com.github.jjbrt.reflection.FieldsHandler class 77 | Methods.invoke(fieldsHandlerClass, executeMethod); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /reflection/src/main/java/com/github/jjbrt/reflection/PackageToModuleExporter.java: -------------------------------------------------------------------------------- 1 | package com.github.jjbrt.reflection; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Modules; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.Resources; 5 | 6 | import java.lang.reflect.Method; 7 | import java.net.URL; 8 | import java.net.URLClassLoader; 9 | 10 | 11 | public class PackageToModuleExporter { 12 | 13 | public static void main(String[] args) { 14 | try { 15 | execute(); 16 | } catch (Throwable exc) { 17 | exc.printStackTrace(); 18 | } 19 | } 20 | 21 | 22 | public static void execute() { 23 | try { 24 | Modules.exportPackageToAllUnnamed("java.base", "java.net"); 25 | Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 26 | method.setAccessible(true); 27 | ClassLoader classLoader = new URLClassLoader(new URL[] {}, null); 28 | method.invoke( 29 | classLoader, 30 | Resources.getClassPath(AllModulesToAllModulesExporter.class).getURL() 31 | ); 32 | Class fieldsHandlerClass = classLoader.loadClass(FieldsHandler.class.getName()); 33 | if (FieldsHandler.class != fieldsHandlerClass) { 34 | System.out.println( 35 | FieldsHandler.class.toString() + " and " + fieldsHandlerClass.toString() + 36 | " are loaded from the same bytecode but they are different instances:" + 37 | "\n\t" + FieldsHandler.class + " is loaded by " + FieldsHandler.class.getClassLoader() + 38 | "\n\t" + fieldsHandlerClass + " is loaded by " + fieldsHandlerClass.getClassLoader() 39 | ); 40 | } 41 | } catch (Exception exc) { 42 | exc.printStackTrace(); 43 | } 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-boot-application-adapter/README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot application adapter 2 | 3 | 4 | To make this project works you need: 5 | 6 | * to set the property '**paths.jdk-home**' of [**burningwave.properties**](https://github.com/JJBRT/advanced-java-tutorials/blob/master/spring-boot-application-adapter/src/test/resources/burningwave.properties#L1) file with a [JDK 8](https://www.oracle.com/it/java/technologies/javase/javase-jdk8-downloads.html) home 7 | 8 | * to run with a [JDK 9](https://www.oracle.com/it/java/technologies/javase-downloads.html) or later the [**DependenciesAdapter**](https://github.com/JJBRT/advanced-java-tutorials/blob/master/spring-boot-application-adapter/src/test/java/org/springbootappadapter/DependenciesAdapter.java) 9 | -------------------------------------------------------------------------------- /spring-boot-application-adapter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.github.jjbrt.java-tutorials 6 | spring-boot-application-adapter 7 | war 8 | Spring Boot application adapter tutorial 9 | Spring Boot application adapter tutorial 10 | 1.0.0 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 1.4.2.RELEASE 16 | 17 | 18 | 19 | 9 20 | 21 | 22 | 23 | 24 | 25 | org.burningwave 26 | tools 27 | 0.27.2 28 | 29 | 30 | 31 | javax.xml.bind 32 | jaxb-api 33 | 2.3.0 34 | 35 | 36 | com.sun.xml.bind 37 | jaxb-impl 38 | 2.3.0 39 | 40 | 41 | org.glassfish.jaxb 42 | jaxb-runtime 43 | 2.3.0 44 | 45 | 46 | javax.activation 47 | activation 48 | 1.1.1 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-web 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-tomcat 58 | provided 59 | 60 | 61 | 62 | javax.servlet 63 | jstl 64 | 65 | 66 | 67 | org.apache.tomcat.embed 68 | tomcat-embed-jasper 69 | provided 70 | 71 | 72 | 73 | org.eclipse.jdt.core.compiler 74 | ecj 75 | 4.6.1 76 | provided 77 | 78 | 79 | 80 | org.webjars 81 | bootstrap 82 | 3.3.7 83 | 84 | 85 | 86 | ch.qos.logback 87 | logback-core 88 | 89 | 90 | 91 | ch.qos.logback 92 | logback-classic 93 | 94 | 95 | 96 | 97 | 98 | 99 | org.springframework.boot 100 | spring-boot-maven-plugin 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/java/com/springbootappadapter/SpringBootWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.springbootappadapter; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.web.support.SpringBootServletInitializer; 7 | import org.springframework.context.ConfigurableApplicationContext; 8 | 9 | @SpringBootApplication 10 | public class SpringBootWebApplication extends SpringBootServletInitializer { 11 | 12 | @Override 13 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 14 | return application.sources(SpringBootWebApplication.class); 15 | } 16 | 17 | public static void main(String[] args) throws Exception { 18 | ConfigurableApplicationContext springContext = SpringApplication.run(SpringBootWebApplication.class, args); 19 | Thread.sleep(10000); 20 | springContext.close(); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/java/com/springbootappadapter/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.springbootappadapter; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | @Controller 10 | public class WelcomeController { 11 | 12 | // inject via application.properties 13 | @Value("${welcome.message:test}") 14 | private String message = "Hello World"; 15 | 16 | @RequestMapping("/") 17 | public String welcome(Map model) { 18 | model.put("message", this.message); 19 | return "welcome"; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix: /WEB-INF/jsp/ 2 | spring.mvc.view.suffix: .jsp 3 | 4 | welcome.message: Hello World -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 9 | 10 | 11 | 12 | 14 | ${LOGS_HOME}/web-core-error.log 15 | 16 | 17 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 18 | 19 | 20 | 21 | ERROR 22 | ACCEPT 23 | 26 | 27 | 28 | WARN 29 | DENY 30 | 31 | 32 | INFO 33 | DENY 34 | 35 | 36 | DEBUG 37 | DENY 38 | 39 | 40 | ${LOGS_HOME}/archived/web-core-error.%d{yyyy-MM-dd}.%i.log 41 | 43 | 25MB 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/resources/static/css/main.css: -------------------------------------------------------------------------------- 1 | h1{ 2 | color:#0000FF; 3 | } 4 | 5 | h2{ 6 | color:#FF0000; 7 | } -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/main/webapp/WEB-INF/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | 2 | <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 | 5 | 6 | 7 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 33 | 34 |
35 | 36 |
37 |

Spring Boot Web JSP Example

38 |

Message: ${message}

39 |
40 | 41 |
42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/test/java/org/springbootappadapter/DependenciesAdapter.java: -------------------------------------------------------------------------------- 1 | package org.springbootappadapter; 2 | 3 | import static org.burningwave.core.assembler.StaticComponentContainer.Driver; 4 | import static org.burningwave.core.assembler.StaticComponentContainer.JVMInfo; 5 | import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collection; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | import org.burningwave.core.assembler.ComponentContainer; 13 | import org.burningwave.core.io.FileSystemItem; 14 | import org.burningwave.core.io.PathHelper; 15 | import org.burningwave.tools.dependencies.Capturer.Result; 16 | import org.burningwave.tools.dependencies.TwoPassCapturer; 17 | 18 | public class DependenciesAdapter { 19 | 20 | 21 | public static void main(String[] args) throws Exception { 22 | long initialTime = System.currentTimeMillis(); 23 | ComponentContainer componentContainer = ComponentContainer.getInstance(); 24 | PathHelper pathHelper = componentContainer.getPathHelper(); 25 | Collection paths = pathHelper.getAllMainClassPaths(); 26 | if (JVMInfo.getVersion() > 8) { 27 | String jdkHome = componentContainer.getConfigProperty("paths.jdk-home"); 28 | if (jdkHome == null || !FileSystemItem.ofPath(jdkHome).exists()) { 29 | String errorMessage = "\"{}\" is not a valid jdk home path: please provide a correct jdk home in the property 'paths.jdk-home' inside the file \"{}\""; 30 | Object[] errorMessageParams = new Object[] { 31 | componentContainer.getConfigProperty("paths.jdk-home"), 32 | pathHelper.getAbsolutePathOfResource("../../../spring-boot-application-adapter/src/test/resources/burningwave.properties") 33 | }; 34 | ManagedLoggerRepository.logError( 35 | () -> DependenciesAdapter.class.getName(), 36 | errorMessage, errorMessageParams 37 | 38 | ); 39 | Driver.throwException(errorMessage, errorMessageParams); 40 | } 41 | paths.addAll(pathHelper.getPaths("dependencies-capturer.additional-resources-path")); 42 | } 43 | List _paths = new ArrayList<>(paths); 44 | Collections.sort(_paths); 45 | Result result = TwoPassCapturer.getInstance().captureAndStore( 46 | "com.springbootappadapter.SpringBootWebApplication", 47 | args, 48 | paths, 49 | System.getProperty("user.home") + "/Desktop/dependencies", 50 | true, 51 | 0L 52 | ); 53 | result.waitForTaskEnding(); 54 | ManagedLoggerRepository.logInfo(() -> DependenciesAdapter.class.getName(), "Elapsed time: " + getFormattedDifferenceOfMillis(System.currentTimeMillis(), initialTime)); 55 | } 56 | 57 | private static String getFormattedDifferenceOfMillis(long value1, long value2) { 58 | String valueFormatted = String.format("%04d", (value1 - value2)); 59 | return valueFormatted.substring(0, valueFormatted.length() - 3) + "," + valueFormatted.substring(valueFormatted.length() -3); 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/test/resources/burningwave.properties: -------------------------------------------------------------------------------- 1 | priority-of-this-configuration-=1 2 | paths.jdk-home=C:/Program Files/Java/jdk1.8.0_251 3 | #paths.jdk-home=F:/Shared/Programmi/Java/jdk/1.8.0_251 4 | paths.dependencies-capturer.additional-resources-path=\ 5 | //${paths.jdk-home}/jre/lib//children:.*\\.jar;\ 6 | //${paths.jdk-home}/jre/lib/ext//children:.*\\.jar;\ 7 | //${paths.jdk-home}/lib/ext//children:.*\\.jar; -------------------------------------------------------------------------------- /spring-boot-application-adapter/src/test/resources/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | priority-of-this-configuration=3 2 | jvm.driver.type=\ 3 | io.github.toolfactory.jvm.DefaultDriver 4 | # io.github.toolfactory.jvm.HybridDriver 5 | # io.github.toolfactory.jvm.NativeDriver 6 | --------------------------------------------------------------------------------