protected void printWelcomeMessage(final Injector injector) {

        final InfoComponent info = injector.getOrThrow(InfoComponent.class);  // Get first
        final InfoComponent upstreamInfo = injector.stream(InfoComponent.class).reduce((first, second) -> second).orElseThrow(NoSuchElementException::new); // Get last
        final String title = info.getTitle();
        final String version = info.getImplementationVersion();

        if (!skipLogoPrintout) {
            final String speedmentMsg = String.format("%n"+
                info.getBanner() + "%n"
                + "   :: " + title + " by " + info.getVendor()
                + ":: (v" + version + ") %n")
                ;

            LOGGER.info(speedmentMsg);
        }
        final String msg = title + " (" + info.getSubtitle() +
                ") version " + version +
                " by " + info.getVendor() +
                " Specification version " +
                info.getSpecificationVersion() +
                " (" + info.getSpecificationNickname() + ")" +
                ", License: " + info.getLicenseName();
        LOGGER.info(msg);
        if (!info.isProductionMode()) {
            LOGGER.warn("This version is NOT INTENDED FOR PRODUCTION USE!");
        }

        if (info != upstreamInfo) {
            LOGGER.info("Upstream version is " + upstreamInfo.getImplementationVersion() + " (" + upstreamInfo.getSpecificationNickname() + ")");
            if (!upstreamInfo.isProductionMode()) {
                LOGGER.warn("Upstream version is NOT INTENDED FOR PRODUCTION USE!");
            }
        }

        try {
            
            final String javaMsg = String.format("%s %s by %s. Implementation %s %s by %s",
                JvmVersion.getSpecificationTitle(), JvmVersion.getSpecificationVersion(), JvmVersion.getSpecificationVendor(),
                JvmVersion.getImplementationTitle(), JvmVersion.getImplementationVersion(), JvmVersion.getImplementationVendor()
            );

            LOGGER.info(javaMsg);

            final String versionString = JvmVersion.getImplementationVersion();
            final Optional<Boolean> isVersionOk = isVersionOk();
            if (isVersionOk.isPresent()) {
                if (!isVersionOk.get()) {
                    LOGGER.warn("The current Java version (" + versionString + 
                        ") is outdated. Please upgrade to a more recent " + 
                        "Java version.");
                }
            } else {
                LOGGER.warn("Unable to fully parse the java version. " + 
                    "Version check skipped!");
            }
        } catch (final Exception ex) {
            LOGGER.info("Unknown Java version.");
        }
        LOGGER.info(
            "Available processors: %d, Max Memory: %,d bytes",
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().maxMemory()
        );

        JpmsUtil.logModulesIfEnabled();

        // Invoke all HasOnWelcome methods
        injector.injectables()
            .flatMap(injector::stream)
            .filter(HasOnWelcome.class::isInstance)
            .map(HasOnWelcome.class::cast)
            .forEach(HasOnWelcome::onWelcome);

    }
Prints a welcome message to the output channel.

@param injector the injector to use
runtime-parent/runtime-application/src/main/java/com/speedment/runtime/application/AbstractApplicationBuilder.java