Play Framework 2.1(Java)eBean @Encrypted Annotation Errors

我正在尝试在字符串字段上为数据库模型使用eBean @Encrypted批注。 文档使它看起来很简单,但是我在浏览器中使用内置的H2内存数据库获得了一个非常模糊的运行时错误:

package models; import java.util.*; import javax.persistence.*; import play.db.ebean.*; import play.db.ebean.Model.Finder; import play.data.format.*; import play.data.validation.*; import com.avaje.ebean.*; import com.avaje.ebean.annotation.*; @Entity public class Test extends Model { @Id public Long id; @Encrypted public String identifier; } 

生成与@Encrypted批注相关的以下运行时错误:

 Unexpected exception RuntimeException: Error reading annotations for models.Test No source available, here is the exception stack trace: ->java.lang.RuntimeException: Error reading annotations for models.Test com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readInitial(ReadAnnotations.java:26) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.createDeployBeanInfo(BeanDescriptorManager.java:1026) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEntityDeploymentInitial(BeanDescriptorManager.java:533) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:250) com.avaje.ebeaninternal.server.core.InternalConfiguration.(InternalConfiguration.java:124) com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:210) com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:64) com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:59) play.db.ebean.EbeanPlugin.onStart(EbeanPlugin.java:79) play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) scala.collection.immutable.List.foreach(List.scala:309) play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:63) play.api.Play$$anonfun$start$1.apply(Play.scala:63) play.api.Play$$anonfun$start$1.apply(Play.scala:63) play.utils.Threads$.withContextClassLoader(Threads.scala:18) play.api.Play$.start(Play.scala:62) play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:133) play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:106) scala.Option.map(Option.scala:145) play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:106) play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:104) scala.util.Either$RightProjection.flatMap(Either.scala:523) play.core.ReloadableApplication.get(ApplicationProvider.scala:104) play.core.server.Server$class.sendHandler$1(Server.scala:56) play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:88) play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:87) scala.util.Either$RightProjection.flatMap(Either.scala:523) play.core.server.Server$class.getHandlerFor(Server.scala:87) play.core.server.NettyServer.getHandlerFor(NettyServer.scala:34) play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:103) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:104) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:455) org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:538) org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:560) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84) org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:472) org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:333) org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35) org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102) org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) java.lang.Thread.run(Thread.java:722) 

我在配置中正确配置了encryptionKeyManager设置(ebean.encryptKeyManager =“com.avaje.tests.basic.encrypt.BasicEncyptKeyManager”)。 一切都很好,没有任何问题甚至警告。

我甚至尝试在项目中手动添加eBean 2.7.1作为依赖项无济于事。

知道这意味着什么以及为什么我会收到此错误?

我相信我可能已经解决了这个问题,但是以一种非常迂回的方式。 问题是,Play Framework无法解析EBean包中的BasicEncryptKeyManager类。 我在查看整个堆栈跟踪时发现了这一点,因为我看到消息“No EncryptKeyManager defined”,即使我在设置文件中明确指定了它(application.conf,ebean.conf,ebean.properties – 你的名字它,我试过它)根据官方文档。

因此,我必须使用ServerConfigStartup从头开始创建自己的(请注意,这只是一个快速而肮脏的示例,可能不是最安全或最有效的方法):

 package models; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.event.ServerConfigStartup; import com.avaje.ebean.config.EncryptKey; import com.avaje.ebean.config.EncryptKeyManager; public class CustomServerConfigStartup implements ServerConfigStartup { @Override public void onStart(ServerConfig serverConfig) { serverConfig.setEncryptKeyManager(new BasicEncryptKeyManager()); } } class BasicEncryptKeyManager implements EncryptKeyManager{ @Override public EncryptKey getEncryptKey(String tableName, String columnName) { return new CustomEncryptKey(tableName, columnName); } @Override public void initialise() { //Do nothing (yet) } } class CustomEncryptKey implements EncryptKey{ private String tableName; private String columnName; public CustomEncryptKey(String tableName, String columnName){ this.tableName = tableName; this.columnName = columnName; } @Override public String getStringValue() { return play.Configuration.root().getString("application.secret") + "::" + this.tableName + "::" + this.columnName; } } 

然后在Play应用程序的conf目录中的application.confebean.properties文件中(此步骤可能是多余的):

 ebean.encryptKeyManager="models.BasicEncryptKeyManager" 

这似乎解决了@Encrypted注释错误。 Play似乎必须在未来某个版本的Ebean实际框架中包含一个可访问的EncryptionKeyManager类,以避免这种解决方法。