我正在尝试在字符串字段上为数据库模型使用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.<init>(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作为依赖项无济于事。
知道这意味着什么以及为什么我会收到此错误?
答案 0 :(得分:7)
我相信我可能已经解决了这个问题,但是以非常迂回的方式解决了这个问题。问题是,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.conf 或 ebean.properties 文件中(此步骤可能是多余的):
ebean.encryptKeyManager="models.BasicEncryptKeyManager"
这似乎解决了@Encrypted注释错误。 Play似乎必须在未来某个版本的Ebean实际框架中包含一个可访问的EncryptionKeyManager类,以避免这种解决方法。