How can I reflect <role-link> as an annotation in EJB 3 - annotations

I try migrate an EJB2.1 projetk into EJB3.1. I did not find any annotation for . How can i reflect this tag.
The ejb-jar.xml part looks like:
<security-role-ref>
<role-name>admin</role-name>
<role-link>adm_role</role-link>
</security-role-ref>

There is no separate annotation, linking security role reference to security role can be done only in deployment descriptor (as in your ejb.jar.xml fragment). This is explained in details at chapter 17.3.3 in EJB 3.1 specification and there is no word about doing it via annotations.

Related

How to specify the context for an EJB in JBOSS

I've got some legacy code that runs in JBoss which looks something like:
#Stateless
#Remote(MyClass.class)
#RemoteBinding(jndiBinding = "app/Service")
public class myServiceBean {
// Some methods
}
When I look up the Bean in JNDI I have to use a string that looks like:
ear-name/Service/remote
I'm OK with the last two parts of the name, but I have an issue with "ear-file" being used as the context name. Because I build with Maven by default ear-file will contain the version number (which I do want for traceability), however it means I would have to change all the references to the service each time I issue a new version of the service!
How do I force the the context to something other than the name of the ear-file?
You can set up your ear name in application.xml like this:
<application-name>ear-name</application-name>
So you can have ear-namexxx.ear but your lookups will be made to ear-name
You can do the same for ejb modules as well:
<ejb-jar>
<module-name>ejb-name</module-name>
</ejb-jar>
Hope it helps!
Source https://developer.jboss.org/thread/158207

Injecting EJB within JAX-RS resource in JBoss 5

Although there already are quite some StackOverflow questions, blog entries, etc. on the web, I still cannot figure out a solution to the problem stated below.
Similar to this question (Injecting EJB within JAX-RS resource on JBoss7) I'd like to inject a EJB instance into a JAX-RS class. I tried with JBoss 5, JBoss 7, and WildFly 8. I either get no injection at all (field is null), or the server does not deploy (as soon as I try to combine all sorts of annotations).
Adding #Stateless to the JAX-RS makes the application server know both classes as beans. However, no injection takes place.
Is there a way to inject EJBs into a REST application? What kind of information (in addition to that contained in the question linked to above) could I provide to help?
EDIT: I created a Github project showing code that works (with Glassfish 4.0) and does not work (with JBoss 5).
https://github.com/C-Otto/beantest
Commit 4bf2f3d23f49d106a435f068ed9b30701bbedc9d works using Glassfish
4.0.
Commit 50d137674e55e1ceb512fe0029b9555ff7c2ec21 uses Jersey 1.8, which does not work.
Commit 86004b7fb6263d66bda7dd302f2d2a714ff3b939
uses Jersey 2.6, which also does not work.
EDIT2:
Running the Code which I tried on JBoss 5 on Glassfish 4.0 gives:
Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403)
EDIT3: The crucial information might be that I'd like a solution that works on JBoss 5
If you don't want to make your JAX-RS resource an EJB too (#Stateless) and then use #EJB or #Resource to inject it, you can always go with JNDI lookup (I tend to write a "ServiceLocator" class that gets a service via its class.
A nice resource to read about the topic:
https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project
A sample code:
try {
// 1. Retreive the Home Interface using a JNDI Lookup
// Retrieve the initial context for JNDI. // No properties needed when local
Context context = new InitialContext();
// Retrieve the home interface using a JNDI lookup using
// the java:comp/env bean environment variable // specified in web.xml
helloHome = (HelloLocalHome) context.lookup("java:comp/env/ejb/HelloBean");
//2. Narrow the returned object to be an HelloHome object. // Since the client is local, cast it to the correct object type.
//3. Create the local Hello bean instance, return the reference
hello = (HelloLocal)helloHome.create();
} catch(NamingException e) {
} catch(CreateException e) {
}
This is not "injecting" per-se, but you don't use "new" as-well, and you let the application server give you an instance which is managed.
I hope this was useful and I'm not telling you something you already know!
EDIT:
This is an excellent example: https://docs.jboss.org/author/display/AS72/EJB+invocations+from+a+remote+client+using+JNDI
EDIT 2:
As you stated in your comment, you'd like to inject it via annotations.
If the JNDI lookup is currently working for you without problems, and
If you're using Java EE 6+ (which I'm guessing you are), you can do the following:
#EJB(lookup = "jndi-lookup-string-here")
private RemoteInterface bean;

Jboss7 ejb bean reference to container-configuration

In my legacy application (jboss 4.2) I have the jboss.xml code like that
...
<entity>
<ejb-name>ClaimCentreRoleBean</ejb-name>
<local-jndi-name>ejb/entity/ClaimCentreRoleLocalHome</local-jndi-name>
<configuration-name>Standard CMP 2.x EntityBean NoLock</configuration-name>
<method-attributes>
<method>
<method-name>get*</method-name>
<read-only>true</read-only>
</method>
</method-attributes>
</entity>
...
which references container configuration Standard CMP 2.x EntityBean NoLock defined in standardjboss.xml as follows
...
<container-configuration extends="Standard CMP 2.x EntityBean">
<container-name>Standard CMP 2.x EntityBean NoLock</container-name>
<locking-policy>org.jboss.ejb.plugins.lock.NoLock</locking-policy>
<commit-option>D</commit-option>
</container-configuration>
...
I googled around and looked through stack-overflow topics, however failed to find any directions how to translate it to jboss7 way? I assume jboss.xml is not supported any more so I need to convert it into jboss-ejb3.xml, which does not support configuration-name attribute.
Have someone experienced the same problem? Any solutions or directions to follow?
Seems the only solution to drop this and comment out.
If some particular interceptors mechanisms are required - then could be added on bean basis (e.g. using <assembly-descriptor>).
Locking - e.g. default-entity-bean-optimistic-locking as per https://docs.jboss.org/author/display/RHQ/JBossAS7+-+Standalone+Server+-+EJB3+Service

Error in BindJndiForEJBNonMessageBinding using ibm-ejb-jar-bnd.xml

Deploying an application in WAS 8 gives me an error:
Cannot find a match for supplied option: "[ejb.jar, ejbName, ejb.jar,META-INF/ibm-ejb-jar-bnd.xml, ejb/ejbName]" for task "BindJndiForEJBNonMessageBinding"
my entry in ibm-ejb-jar-bnd.xml
<session name="ejbName">
<interface class="com.manager.EJBNameManager" binding-name="ejb/ejbName"/></session>
my entry in deploy.jacl
[-BindJndiForEJBNonMessageBinding ejb.jar ejbName ejb.jar,META-INF/ibm-ejb-jar-bnd.xml ejb/ejbName]
my ejb.jar structure has META-INF/ibm-ejb-jar-bnd.xml also.
Was my entry in ibm-ejb-jar-bnd.xml correct? Please enlighten me on this one. Thanks.
Instead of providing the path to your ejb jar bindings (ejb.jar,META-INF/ibm-ejb-jar-bnd.xml), you should be providing the path to your ejb deployment descriptor (e.g. ejb.jar,META-INF/ejb-jar.xml).
In addition, you shouldn't even need the ejb bindings file, because you are creating the binding using JACL. The ibm-ejb-jar-bnd.xml file will automatically be created for you as a result of your deployment.
(Also, as a side note, WAS deprecated its use of JACL in WAS 7, so you should consider using jython for your wsadmin scripts instead.)

Correct way to make datasources/resources a deploy-time setting

I have a web-app that requires two settings:
A JDBC datasource
A string token
I desperately want to be able to deploy one .war to various different containers (jetty,tomcat,gf3 minimum) and configure these settings at application level within the container.
My code does this:
InitialContext ctx = new InitialContext();
Context envCtx = (javax.naming.Context) ctx.lookup("java:comp/env");
token = (String)envCtx.lookup("token");
ds = (DataSource)envCtx.lookup("jdbc/datasource")
Let's assume I've used the glassfish management interface to create two jdbc resources: jdbc/test-datasource and jdbc/live-datasource which connect to different copies of the same schema, on different servers, different credentials etc. Say I want to deploy this to glassfish with and point it at the test datasource, I might have this in my sun-web.xml:
...
<resource-ref>
<res-ref-name>jdbc/datasource</res-ref-name>
<jndi-name>jdbc/test-datasource</jndi-name>
</resource-ref>
...
but
sun-web.xml goes inside my war, right?
surely there must be a way to do this through the management interface
Am I even trying to do the right thing? Do other containers make this any easier? I'd be particularly interested in how jetty 7 handles this since I use it for development.
EDIT Tomcat has a reasonable way to do this:
Create $TOMCAT_HOME/conf/Catalina/localhost/webapp.xml with:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
<!-- String resource -->
<Environment name="token" value="value of token" type="java.lang.String" override="false" />
<!-- Linking to a global resource -->
<ResourceLink name="jdbc/datasource1" global="jdbc/test" type="javax.sql.DataSource" />
<!-- Derby -->
<Resource name="jdbc/datasource2"
type="javax.sql.DataSource"
auth="Container"
driverClassName="org.apache.derby.jdbc.EmbeddedDataSource"
url="jdbc:derby:test;create=true"
/>
<!-- H2 -->
<Resource name="jdbc/datasource3"
type="javax.sql.DataSource"
auth="Container"
driverClassName="org.h2.jdbcx.JdbcDataSource"
url="jdbc:h2:~/test"
username="sa"
password=""
/>
</Context>
Note that override="false" means the opposite. It means that this setting can't be overriden by web.xml.
I like this approach because the file is part of the container configuration not the war, but it's not part of the global configuration; it's webapp specific.
I guess I expect a bit more from glassfish since it is supposed to have a full web admin interface, but I would be happy enough with something equivalent to the above.
For GF v3, you may want to try leveraging the --deploymentplan option of the deploy subcommand of asadmin. It is discussed on the man page for the deploy subcommand.
We had just this issue when migrating from Tomcat to Glassfish 3. Here is what works for us.
In the Glassfish admin console, configure datasources (JDBC connection pools and resources) for DEV/TEST/PROD/etc.
Record your deployment time parameters (in our case database connect info) in properties file. For example:
# Database connection properties
dev=jdbc/dbdev
test=jdbc/dbtest
prod=jdbc/dbprod
Each web app can load the same database properties file.
Lookup the JDBC resource as follows.
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* #param resourceName the resource name of the connection pool (eg jdbc/dbdev)
* #return Connection a pooled connection from the data source
* associated with resourceName
* #throws NamingException will be thrown if resource name is not found
*/
public Connection getDatabaseConnection(String resourceName)
throws NamingException, SQLException {
Context initContext = new InitialContext();
DataSource pooledDataSource = (DataSource) initContext.lookup(resourceName);
return pooledDataSource.getConnection();
}
Note that this is not the usual two step process involving a look up using the naming context "java:comp/env." I have no idea if this works in application containers other than GF3, but in GF3 there is no need to add resource descriptors to web.xml when using the above approach.
I'm not sure to really understand the question/problem.
As an Application Component Provider, you declare the resource(s) required by your application in a standard way (container agnostic) in the web.xml.
At deployment time, the Application Deployer and Administrator is supposed to follow the instructions provided by the Application Component Provider to resolve external dependencies (amongst other things) for example by creating a datasource at the application server level and mapping its real JNDI name to the resource name used by the application through the use of an application server specific deployment descriptor (e.g. the sun-web.xml for GlassFish). Obviously, this is a container specific step and thus not covered by the Java EE specification.
Now, if you want to change the database an application is using, you'll have to either:
change the mapping in the application server deployment descriptor - or -
modify the configuration of the existing datasource to make it points on another database.
Having an admin interface doesn't really change anything. If I missed something, don't hesitate to let me know. And just in case, maybe have a look at this previous answer.