synchronized ( kieFileSystem ) {
//KieBuilder is not re-usable for successive "full" builds
kieBuilder = kieServices.newKieBuilder( kieFileSystem );
//Record RTEs from KieBuilder - that can fail if a rule uses an inaccessible class
final BuildResults results = new BuildResults( gav );
try {
final Results kieResults = kieBuilder.buildAll().getResults();
for ( final Message message : kieResults.getMessages() ) {
results.addBuildMessage( convertMessage( message ) );
}
//It's impossible to retrieve a KieContainer if the KieModule contains errors
if ( results.getErrorMessages().isEmpty() ) {
kieContainer = kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId() );
} else {
kieContainer = null;
}
} catch ( LinkageError e ) {
final String msg = MessageFormat.format( ERROR_CLASS_NOT_FOUND,
e.getLocalizedMessage() );
logger.warn( msg, e );
results.addBuildMessage( makeWarningMessage( msg ) );
} catch ( Throwable e ) {
final String msg = e.getLocalizedMessage();
logger.error( msg, e );
results.addBuildMessage( makeErrorMessage( msg ) );
}
//Add validate messages from external helpers
for ( Map.Entry<Path, BuildValidationHelper> e : nonKieResourceValidationHelpers.entrySet() ) {
final org.uberfire.backend.vfs.Path vfsPath = Paths.convert( e.getKey() );
final List<ValidationMessage> validationMessages = e.getValue().validate( vfsPath );
nonKieResourceValidationHelperMessages.put( e.getKey(),
validationMessages );
if ( !( validationMessages == null || validationMessages.isEmpty() ) ) {
for ( ValidationMessage validationMessage : validationMessages ) {
results.addBuildMessage( convertValidationMessage( validationMessage ) );
}
}
}
//Check external imports are available. These are loaded when a DMO is requested, but it's better to report them early
final org.uberfire.java.nio.file.Path nioExternalImportsPath = moduleDirectory.resolve( "project.imports" );
if ( Files.exists( nioExternalImportsPath ) ) {
final org.uberfire.backend.vfs.Path externalImportsPath = Paths.convert( nioExternalImportsPath );
final ProjectImports projectImports = projectService.load( externalImportsPath );
final Imports imports = projectImports.getImports();
for ( final Import item : imports.getImports() ) {
final String fullyQualifiedClassName = item.getType();
try {
Class clazz = this.getClass().getClassLoader().loadClass( item.getType() );
} catch ( ClassNotFoundException cnfe ) {
logger.error( cnfe.getMessage(), cnfe );
final String msg = MessageFormat.format( ERROR_CLASS_NOT_FOUND,
fullyQualifiedClassName );
results.addBuildMessage( makeWarningMessage( msg ) );
}
}
}
//At the end we are interested to ensure that external .jar files referenced as dependencies don't have
// referential inconsistencies. We will at least provide a basic algorithm to ensure that if an external class
// X references another external class Y, Y is also accessible by the class loader.
final KieModuleMetaData kieModuleMetaData = getKieModuleMetaData();
for ( final String packageName : kieModuleMetaData.getPackages() ) {
for ( final String className : kieModuleMetaData.getClasses( packageName ) ) {
final String fullyQualifiedClassName = packageName + "." + className;
try {
final Class clazz = kieModuleMetaData.getClass( packageName,
className );
if ( clazz != null ) {
final TypeSource typeSource = getClassSource( kieModuleMetaData,
clazz );
if ( TypeSource.JAVA_DEPENDENCY == typeSource ) {
verifyExternalClass( clazz );
}
} else {
final String msg = MessageFormat.format( ERROR_EXTERNAL_CLASS_VERIFICATON,
fullyQualifiedClassName );
logger.warn( msg );
}
} catch ( Throwable e ) {
final String msg = MessageFormat.format( ERROR_EXTERNAL_CLASS_VERIFICATON,
fullyQualifiedClassName );
logger.warn( msg, e );
results.addBuildMessage( makeWarningMessage( msg ) );
}
}
}
return results;