问题
I wonder if it is possible to use Hibernate Validator on Android. I tried but it looks like some javax packages are missing on Android platform (javax.xml.stream.XMLInputFactory).
Here is my code, dependency and error:
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
03-28 10:07:15.562 6477-6477/foo E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: foo, PID: 6477
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/stream/XMLInputFactory;
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.xml.stream.XMLInputFactory" on path: DexPathList[[zip file "/data/app/foo-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.hibernate.validator.internal.xml.XmlParserHelper.<init>(XmlParserHelper.java:66)
at org.hibernate.validator.internal.xml.ValidationXmlParser.<init>(ValidationXmlParser.java:60)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at foo.FooActivity.onCreate(FooActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: javax.xml.stream.XMLInputFactory
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 21 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
回答1:
I managed to solve this. Due to lack of xml packages we have to disable this option in configuration. Here is my proposed solution.
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
It's necessary to have following dependencies:
compile 'org.hibernate:hibernate-validator:5.1.3.Final'
compile 'javax.el:javax.el-api:2.2.4'
compile 'org.glassfish.web:javax.el:2.2.4'
For custom messages from strings resources, MessageInterpolator has to be implemented. First of all Application must be extended for access to global context all over project.
public class ApplicationContext extends Application {
private static Application application;
@Override
public void onCreate() {
super.onCreate();
application = this;
}
public static Application getApplication() {
return application;
}
}
Configuration:
ValidatorFactory validatorFactory = Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.messageInterpolator(new MessageInterpolator() {
@Override
public String interpolate(String messageTemplate, Context context) {
int id = ApplicationContext.getApplication().getResources().getIdentifier(messageTemplate, "string", R.class.getPackage().getName());
return ApplicationContext.getApplication().getString(id);
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
return interpolate(messageTemplate, context);
}
})
.buildValidatorFactory();
Example:
@NotEmpty(message = "error_empty")
private String foo;
<resources>
<string name="error_empty">Cannot be empty</string>
</resources>
来源:https://stackoverflow.com/questions/29315472/android-and-hibernate-validator-it-is-possible-to-use-together