Estoy tratando de ejecutar un simple NaiveBayesClassifer
utilizando hadoop, obteniendo este error
Exception in thread "main" java.io.IOException: No FileSystem for scheme: file
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:1375)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:66)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:1390)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:196)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:95)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:180)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:175)
at org.apache.mahout.classifier.naivebayes.NaiveBayesModel.materialize(NaiveBayesModel.java:100)
Código:
Configuration configuration = new Configuration();
NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), configuration);// error in this line..
modelPath
está apuntando al archivo NaiveBayes.bin
, y el objeto de configuración está imprimiendo - Configuration: core-default.xml, core-site.xml
Creo que es debido a los frascos, ¿alguna idea?
Este es un caso típico del plugin maven-assembly
rompiendo cosas.
Diferentes JARs (hadoop-commons
para LocalFileSystem
, hadoop-hdfs
para DistributedFileSystem
) contienen cada uno un archivo diferente llamado org.apache.hadoop.fs.FileSystem
en su directorio META-INFO/services
. Este fichero lista los nombres de clase canónicos de las implementaciones del sistema de ficheros que quieren declarar (Esto se llama una Interfaz de Proveedor de Servicios implementada a través de java.util.ServiceLoader
, ver org.apache.hadoop.FileSystem
línea 2622).
Cuando usamos maven-assembly-plugin
, se fusionan todos nuestros JARs en uno, y todos los META-INFO/services/org.apache.hadoop.fs.FileSystem
se sobrescriben entre sí. Sólo queda uno de estos archivos (el último que se añadió). En este caso, la lista FileSystem
de hadoop-commons
sobrescribe la lista de hadoop-hdfs
, por lo que DistributedFileSystem
ya no se declara.
Después de cargar la configuración de Hadoop, pero justo antes de hacer nada relacionado con FileSystem
, llamamos a esto:
hadoopConfig.set("fs.hdfs.impl",
org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()
);
hadoopConfig.set("fs.file.impl",
org.apache.hadoop.fs.LocalFileSystem.class.getName()
);
Me ha llamado la atención krookedking
que hay una manera basada en la configuración para hacer que el maven-assembly
utilice una versión fusionada de todas las declaraciones de servicios FileSystem
, echa un vistazo a su respuesta a continuación.
Suponiendo que usted está utilizando mvn y cloudera distribución de hadoop. I'm usando cdh4.6 y la adición de estas dependencias trabajado para me.I creo que usted debe comprobar las versiones de hadoop y dependencias mvn.
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>2.0.0-mr1-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
don't forget to add cloudera mvn repository.
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
Asumo que construyes la muestra usando maven.
Por favor, compruebe el contenido del JAR que está intentando ejecutar. Especialmente el directorio META-INFO/services
, archivo org.apache.hadoop.fs.FileSystem
. Debería haber una lista de clases de implementación de filsystem. Compruebe la línea org.apache.hadoop.hdfs.DistributedFileSystem
está presente en la lista para HDFS y org.apache.hadoop.fs.LocalFileSystem
para el esquema de archivos locales.
Si este es el caso, usted tiene que anular recurso referido durante la construcción.
Otra posibilidad es que simplemente no tengas hadoop-hdfs.jar
en tu classpath, pero esto es poco probable. Por lo general, si usted tiene la dependencia correcta hadoop-client
no es una opción.