Seam RESTeasy integration HTTP 403
many Aug 7, 2011 3:43 PMI've been working on this for a while and however it seems that something has to do with the ResourceHome compponent, still not sure where the problem is! needless to say I would appreciate any help.
I'm working with jboss-seam-2.1.2 and application server jboss-5.1.0.GA also using ResourceHome components configured by subclassing ResourceHome approach:
When run the following request:
http://localhost:8080/product/seam/resource/rest/extendedStatus
on the client I get the following output:
HTTP Status 403 - Access to the requested resource has been denied
At the debug.seam I got the following message:
org.jboss.resteasy.spi.UnhandledException: java.lang.RuntimeException: Unable to determine entity id class.
This is the output on the server.log:
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Security checking request GET /product/seam/resource/debug.xhtml
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Calling hasUserDataPermission()
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) User data constraint has no restrictions
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Calling accessControl()
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking roles null
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) No roles
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Failed accessControl() test
Now These are the classes:
@Name("statusResourceHome")
@Path("extendedStatus")
public class StatusResourceHome extends ResourceHome<Status, Long>
{
@In(create=true)
private EntityHome<Status> statusHome;
@Override
public Home <?, Status> getEntityHome()
{
return statusHome;
}
/**
* Constructor
*/
public StatusResourceHome()
{
setMediaTypes(new String[] { "application/xml", "application/json" });
}
}
---------------------------------------------------------------------------
@Name("statusHome")
@AutoCreate
public class StatusHome extends EntityHome<Status>
{
public void setStatusInternalKey(Long id)
{
setId(id);
}
public Long getStatusInternalKey()
{
return (Long) getId();
}
@Override
protected Status createInstance()
{
Status status = new Status();
return status;
}
public void load()
{
if (isIdDefined())
{
wire();
}
}
public void wire()
{
getInstance();
}
public boolean isWired()
{
return true;
}
public Status getDefinedInstance()
{
return isIdDefined() ? getInstance() : null;
}
}
---------------------------------------------------------
finally the entity
@Entity
@Table(name = "enrollment_status")
@XmlRootElement
public class Status implements java.io.Serializable {
private Long internalKey;
private Long version;
private Date created;
private byte[] author;
private Date lastUpdated;
private byte[] lastUpdatedBy;
private Character value;
private String text;
private String subtext;
public Status() {
}
public Status(Date created, byte[] author, Date lastUpdated,
byte[] lastUpdatedBy, Character value, String text, String subtext) {
this.created = created;
this.author = author;
this.lastUpdated = lastUpdated;
this.lastUpdatedBy = lastUpdatedBy;
this.value = value;
this.text = text;
this.subtext = subtext;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "internalKey", unique = true, nullable = false)
public Long getInternalKey() {
return this.internalKey;
}
public void setInternalKey(Long internalKey) {
this.internalKey = internalKey;
}
@Version
@Column(name = "version")
public Long getVersion() {
return this.version;
}
public void setVersion(Long version) {
this.version = version;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created", length = 19)
public Date getCreated() {
return this.created;
}
public void setCreated(Date created) {
this.created = created;
}
@Column(name = "createdBy")
public byte[] getAuthor() {
return this.author;
}
public void setAuthor(byte[] author) {
this.author = author;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "lastUpdated", length = 19)
public Date getLastUpdated() {
return this.lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
@Column(name = "lastUpdatedBy")
public byte[] getLastUpdatedBy() {
return this.lastUpdatedBy;
}
public void setLastUpdatedBy(byte[] lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
@Column(name = "value", length = 1)
public Character getValue() {
return this.value;
}
public void setValue(Character value) {
this.value = value;
}
@Column(name = "text", length = 16)
@Length(max = 16)
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
@Column(name = "subtext", length = 64)
@Length(max = 64)
public String getSubtext() {
return this.subtext;
}
public void setSubtext(String subtext) {
this.subtext = subtext;
}
}
-------------------------------------------------------------------
on the components.xml
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:persistence="http://jboss.com/products/seam/persistence"
xmlns:drools="http://jboss.com/products/seam/drools"
xmlns:bpm="http://jboss.com/products/seam/bpm"
xmlns:async="http://jboss.com/products/seam/async"
xmlns:resteasy="http://jboss.com/products/seam/resteasy"
xmlns:framework="http://jboss.com/products/seam/framework"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:mail="http://jboss.com/products/seam/mail"
xmlns:web="http://jboss.com/products/seam/web"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd
http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.1.xsd
http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd
http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.1.xsd
http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd
http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.1.xsd
http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.1.xsd
http://jboss.com/products/seam/resteasy http://jboss.com/products/seam/resteasy-2.1.xsd
http://jboss.com/products/seam/framework http://jboss.com/products/seam/framework-2.1.xsd
http://jboss.com/products/seam/async http://jboss.com/products/seam/async-2.1.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">
<core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
<core:manager concurrent-request-timeout="500"
conversation-timeout="120000"
conversation-id-parameter="cid"
parent-conversation-id-parameter="pid"/>
<!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
<web:hot-deploy-filter url-pattern="*.seam"/>
<persistence:managed-persistence-context name="entityManager" auto-create="true"
persistence-unit-jndi-name="java:/productEntityManagerFactory"/>
<async:quartz-dispatcher/>
<drools:rule-base name="securityRules">
<drools:rule-files>
<value>/security.drl</value>
</drools:rule-files>
</drools:rule-base>
<security:rule-based-permission-resolver security-rules="#{securityRules}"/>
<security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}"/>
</event>
<event type="org.jboss.seam.security.loginSuccessful">
<action execute="#{redirect.returnToCapturedView}"/>
</event>
<mail:mail-session host="localhost" port="25"/>
<!-- For use with jBPM pageflow or process management -->
<!--
<bpm:jbpm>
<bpm:process-definitions></bpm:process-definitions>
<bpm:pageflow-definitions></bpm:pageflow-definitions>
</bpm:jbpm>
-->
</components>
---------------------------------------------------------------------------
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Persistence deployment descriptor for dev profile -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="product">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>productDatasource</jta-data-source>
<!-- The <jar-file> element is necessary if you put the persistence.xml in the WAR and the classes in the JAR -->
<!--
<jar-file>../../vehicles.jar</jar-file>
-->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.default_catalog" value="accounts"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/productEntityManagerFactory"/>
</properties>
</persistence-unit>
</persistence>
I'm working with jboss-seam-2.1.2 and application server jboss-5.1.0.GA also using ResourceHome components configured by subclassing ResourceHome approach:
When run the following request:
http://localhost:8080/product/seam/resource/rest/extendedStatus
on the client I get the following output:
HTTP Status 403 - Access to the requested resource has been denied
At the debug.seam I got the following message:
org.jboss.resteasy.spi.UnhandledException: java.lang.RuntimeException: Unable to determine entity id class.
This is the output on the server.log:
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Security checking request GET /product/seam/resource/debug.xhtml
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking constraint 'SecurityConstraint[XHTML]' against GET /seam/resource/debug.xhtml --> true
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Calling hasUserDataPermission()
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) User data constraint has no restrictions
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Calling accessControl()
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) Checking roles null
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.realm.RealmBase] (http-127.0.0.1-8080-6) No roles
2011-08-07 13:42:23,278 DEBUG [org.apache.catalina.authenticator.AuthenticatorBase] (http-127.0.0.1-8080-6) Failed accessControl() test
Now These are the classes:
@Name("statusResourceHome")
@Path("extendedStatus")
public class StatusResourceHome extends ResourceHome<Status, Long>
{
@In(create=true)
private EntityHome<Status> statusHome;
@Override
public Home <?, Status> getEntityHome()
{
return statusHome;
}
/**
* Constructor
*/
public StatusResourceHome()
{
setMediaTypes(new String[] { "application/xml", "application/json" });
}
}
---------------------------------------------------------------------------
@Name("statusHome")
@AutoCreate
public class StatusHome extends EntityHome<Status>
{
public void setStatusInternalKey(Long id)
{
setId(id);
}
public Long getStatusInternalKey()
{
return (Long) getId();
}
@Override
protected Status createInstance()
{
Status status = new Status();
return status;
}
public void load()
{
if (isIdDefined())
{
wire();
}
}
public void wire()
{
getInstance();
}
public boolean isWired()
{
return true;
}
public Status getDefinedInstance()
{
return isIdDefined() ? getInstance() : null;
}
}
---------------------------------------------------------
finally the entity
@Entity
@Table(name = "enrollment_status")
@XmlRootElement
public class Status implements java.io.Serializable {
private Long internalKey;
private Long version;
private Date created;
private byte[] author;
private Date lastUpdated;
private byte[] lastUpdatedBy;
private Character value;
private String text;
private String subtext;
public Status() {
}
public Status(Date created, byte[] author, Date lastUpdated,
byte[] lastUpdatedBy, Character value, String text, String subtext) {
this.created = created;
this.author = author;
this.lastUpdated = lastUpdated;
this.lastUpdatedBy = lastUpdatedBy;
this.value = value;
this.text = text;
this.subtext = subtext;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "internalKey", unique = true, nullable = false)
public Long getInternalKey() {
return this.internalKey;
}
public void setInternalKey(Long internalKey) {
this.internalKey = internalKey;
}
@Version
@Column(name = "version")
public Long getVersion() {
return this.version;
}
public void setVersion(Long version) {
this.version = version;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created", length = 19)
public Date getCreated() {
return this.created;
}
public void setCreated(Date created) {
this.created = created;
}
@Column(name = "createdBy")
public byte[] getAuthor() {
return this.author;
}
public void setAuthor(byte[] author) {
this.author = author;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "lastUpdated", length = 19)
public Date getLastUpdated() {
return this.lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
@Column(name = "lastUpdatedBy")
public byte[] getLastUpdatedBy() {
return this.lastUpdatedBy;
}
public void setLastUpdatedBy(byte[] lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
@Column(name = "value", length = 1)
public Character getValue() {
return this.value;
}
public void setValue(Character value) {
this.value = value;
}
@Column(name = "text", length = 16)
@Length(max = 16)
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
@Column(name = "subtext", length = 64)
@Length(max = 64)
public String getSubtext() {
return this.subtext;
}
public void setSubtext(String subtext) {
this.subtext = subtext;
}
}
-------------------------------------------------------------------
on the components.xml
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:persistence="http://jboss.com/products/seam/persistence"
xmlns:drools="http://jboss.com/products/seam/drools"
xmlns:bpm="http://jboss.com/products/seam/bpm"
xmlns:async="http://jboss.com/products/seam/async"
xmlns:resteasy="http://jboss.com/products/seam/resteasy"
xmlns:framework="http://jboss.com/products/seam/framework"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:mail="http://jboss.com/products/seam/mail"
xmlns:web="http://jboss.com/products/seam/web"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd
http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.1.xsd
http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd
http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.1.xsd
http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd
http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.1.xsd
http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.1.xsd
http://jboss.com/products/seam/resteasy http://jboss.com/products/seam/resteasy-2.1.xsd
http://jboss.com/products/seam/framework http://jboss.com/products/seam/framework-2.1.xsd
http://jboss.com/products/seam/async http://jboss.com/products/seam/async-2.1.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">
<core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
<core:manager concurrent-request-timeout="500"
conversation-timeout="120000"
conversation-id-parameter="cid"
parent-conversation-id-parameter="pid"/>
<!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
<web:hot-deploy-filter url-pattern="*.seam"/>
<persistence:managed-persistence-context name="entityManager" auto-create="true"
persistence-unit-jndi-name="java:/productEntityManagerFactory"/>
<async:quartz-dispatcher/>
<drools:rule-base name="securityRules">
<drools:rule-files>
<value>/security.drl</value>
</drools:rule-files>
</drools:rule-base>
<security:rule-based-permission-resolver security-rules="#{securityRules}"/>
<security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}"/>
</event>
<event type="org.jboss.seam.security.loginSuccessful">
<action execute="#{redirect.returnToCapturedView}"/>
</event>
<mail:mail-session host="localhost" port="25"/>
<!-- For use with jBPM pageflow or process management -->
<!--
<bpm:jbpm>
<bpm:process-definitions></bpm:process-definitions>
<bpm:pageflow-definitions></bpm:pageflow-definitions>
</bpm:jbpm>
-->
</components>
---------------------------------------------------------------------------
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Persistence deployment descriptor for dev profile -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="product">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>productDatasource</jta-data-source>
<!-- The <jar-file> element is necessary if you put the persistence.xml in the WAR and the classes in the JAR -->
<!--
<jar-file>../../vehicles.jar</jar-file>
-->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.default_catalog" value="accounts"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/productEntityManagerFactory"/>
</properties>
</persistence-unit>
</persistence>