private static boolean patchShadedLibraryId ( byte [ ] bytes , String originalName , String name ) { // Our native libs always have the name as part of their id so we can search for it and replace it // to make the ID unique if shading is used. byte [ ] nameBytes = originalName . getBytes ( CharsetUtil . UTF_8 ) ; int idIdx = - 1 ; // Be aware this is a really raw way of patching a dylib but it does all we need without implementing // a full mach-o parser and writer. Basically we just replace the the original bytes with some // random bytes as part of the ID regeneration. The important thing here is that we need to use the same // length to not corrupt the mach-o header. outerLoop : for ( int i = 0 ; i < bytes . length && bytes . length - i >= nameBytes . length ; i ++ ) { int idx = i ; for ( int j = 0 ; j < nameBytes . length ; ) { if ( bytes [ idx ++ ] != nameBytes [ j ++ ] ) { // Did not match the name, increase the index and try again. break ; } else if ( j == nameBytes . length ) { // We found the index within the id. idIdx = i ; break outerLoop ; } } } if ( idIdx == - 1 ) { logger . debug ( "Was not able to find the ID of the shaded native library {}, can't adjust it." , name ) ; return false ; } else { // We found our ID... now monkey-patch it! for ( int i = 0 ; i < nameBytes . length ; i ++ ) { // We should only use bytes as replacement that are in our UNIQUE_ID_BYTES array. bytes [ idIdx + i ] = UNIQUE_ID_BYTES [ PlatformDependent . threadLocalRandom ( ) . nextInt ( UNIQUE_ID_BYTES . length ) ] ; } if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Found the ID of the shaded native library {}. Replacing ID part {} with {}" , name , originalName , new String ( bytes , idIdx , nameBytes . length , CharsetUtil . UTF_8 ) ) ; } return true ; } }
Try to patch shaded library to ensure it uses a unique ID .