KarafBoot implements IPentahoSystemListener { @Override public boolean startup( IPentahoSession session ) { try { String solutionRootPath = PentahoSystem.getApplicationContext().getSolutionRootPath(); File karafDir = new File( solutionRootPath + KARAF_DIR ); if ( !karafDir.exists() ) { logger.warn( "Karaf not found in standard dir of '" + ( solutionRootPath + KARAF_DIR ) + "' " ); String osxAppRootDir = System.getProperty( SYSTEM_PROP_OSX_APP_ROOT_DIR ); if ( !StringUtils.isEmpty( osxAppRootDir ) ) { logger.warn( "Given that the system property '" + SYSTEM_PROP_OSX_APP_ROOT_DIR + "' is set, we are in " + "a OSX .app context; we'll try looking for Karaf in the app's root dir '" + osxAppRootDir + "' " ); File osxAppKarafDir = new File( osxAppRootDir + KARAF_DIR ); if ( osxAppKarafDir.exists() ) { karafDir = osxAppKarafDir; } } } String root = karafDir.getAbsolutePath(); String rootCopyFolderString = System.getProperty( PENTAHO_KARAF_ROOT_COPY_DEST_FOLDER ); boolean transientRoot = Boolean.parseBoolean( System.getProperty( PENTAHO_KARAF_ROOT_TRANSIENT, "false" ) ); if ( rootCopyFolderString == null && !canOpenConfigPropertiesForEdit( root ) ) { transientRoot = true; } final File destDir; if ( transientRoot ) { if ( rootCopyFolderString == null ) { destDir = Files.createTempDirectory( "karaf" ).toFile(); } else { int directoryAttempts = Integer.parseInt( System.getProperty( PENTAHO_KARAF_ROOT_TRANSIENT_DIRECTORY_ATTEMPTS, "250" ) ); File candidate = new File( rootCopyFolderString ); int i = 1; while ( candidate.exists() || !candidate.mkdirs() ) { if ( i > directoryAttempts ) { candidate = Files.createTempDirectory( "karaf" ).toFile(); logger.warn( "Unable to create " + rootCopyFolderString + " after " + i + " attempts, using temp dir " + candidate ); break; } candidate = new File( rootCopyFolderString + ( i++ ) ); } destDir = candidate; } Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() { @Override public void run() { try { if ( main != null ) { main.destroy(); } if ( karafInstance != null ) { karafInstance.close(); } deleteRecursiveIfExists( destDir ); } catch ( IOException e ) { logger.error( "Unable to delete karaf directory " + destDir, e ); } catch ( Exception e ) { logger.error( "Error stopping Karaf", e ); } } } ) ); } else if ( rootCopyFolderString != null ) { destDir = new File( rootCopyFolderString ); } else { destDir = null; } if ( destDir != null && ( transientRoot || !destDir.exists() ) ) { final Set<String> symlinks = new HashSet<>(); String symlinkFiles = System.getProperty( PENTAHO_KARAF_ROOT_COPY_FOLDER_SYMLINK_FILES, "lib,system" ); if ( symlinkFiles != null ) { for ( String symlink : symlinkFiles.split( "," ) ) { symlinks.add( symlink.trim() ); } } final Set<String> excludes = new HashSet<>(); String excludeFiles = System.getProperty( PENTAHO_KARAF_ROOT_COPY_FOLDER_EXCLUDE_FILES, "caches" ); if ( excludeFiles != null ) { for ( String exclude : excludeFiles.split( "," ) ) { excludes.add( exclude.trim() ); } } final Path karafDirPath = Paths.get( karafDir.toURI() ); FileUtils.copyDirectory( karafDir, destDir, new AbstractFileFilter() { @Override public boolean accept( File file ) { Path filePath = Paths.get( file.toURI() ); String relativePath = karafDirPath.relativize( filePath ).toString(); if ( excludes.contains( relativePath ) ) { return false; } else if ( symlinks.contains( relativePath ) ) { File linkFile = new File( destDir, relativePath ); try { boolean linkFileDirCreated = linkFile.getParentFile().mkdirs(); logger.info( "link file " + linkFile.getParentFile().getAbsolutePath() + ( linkFileDirCreated ? "created" : "already existed" ) ); } catch ( SecurityException exception ) { logger.error( linkFile.getParentFile().getAbsolutePath() + " Access denied." ); throw exception; } Path link = Paths.get( linkFile.toURI() ); try { if ( Files.createSymbolicLink( link, filePath ) != null ) { return false; } } catch ( IOException e ) { logger.warn( "Unable to create symlink " + linkFile.getAbsolutePath() + " -> " + file.getAbsolutePath() ); } } return true; } } ); } if ( destDir != null ) { root = destDir.toURI().getPath(); } this.karafCustomProperties = this.readCustomProperties( root ); configureSystemProperties( solutionRootPath, root ); expandSystemPackages(); cleanCachesIfFlagSet( root ); karafInstance = createAndProcessKarafInstance( root ); Thread karafThread = new Thread( new Runnable() { @Override public void run() { SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken( UUID.randomUUID().toString(), "" ) ); main = new Main( new String[ 0 ] ); try { main.launch(); } catch ( Exception e ) { main = null; logger.error( "Error starting Karaf", e ); } } } ); karafThread.setDaemon( true ); karafThread.run(); karafThread.join(); } catch ( Exception e ) { main = null; logger.error( "Error starting Karaf", e ); } this.karafCustomProperties = null; return main != null; }  @Override boolean startup( IPentahoSession session ); @Override void shutdown(); static final String CLEAN_KARAF_CACHE; static final String PENTAHO_KARAF_ROOT_COPY_DEST_FOLDER; static final String PENTAHO_KARAF_ROOT_TRANSIENT; static final String PENTAHO_KARAF_ROOT_TRANSIENT_DIRECTORY_ATTEMPTS; static final String PENTAHO_KARAF_ROOT_COPY_FOLDER_SYMLINK_FILES; static final String PENTAHO_KARAF_ROOT_COPY_FOLDER_EXCLUDE_FILES; static final String ORG_OSGI_FRAMEWORK_SYSTEM_PACKAGES_EXTRA; static final String PENTAHO_KARAF_INSTANCE_RESOLVER_CLASS; }
@Test public void testStartup() throws Exception { String origKarafHome = System.getProperty( "karaf.home" ); try { System.getProperties().remove( "karaf.home" ); doReturn( karafInstance ).when( boot ).createAndProcessKarafInstance( anyString() ); boolean startup = boot.startup( session ); assertFalse( startup ); assertEquals( tmpDir.getAbsolutePath(), new File( System.getProperty( "karaf.home" ) ).getParentFile().getParentFile().getAbsolutePath() ); } finally { if ( origKarafHome == null ) { System.getProperties().remove( "karaf.home" ); } else { System.setProperty( "karaf.home", origKarafHome ); } } }