Wildfly 10 / NetBeans 8.2: Issue creating Message-driven Bean - netbeans

I have a problem after adding a message queue to Wildfly 10.1 (I'm using NetBeans 8.2). The message queue appears under the Resources/JMS Resources/JMS Destinations node in Wildfly Application Server, but when I create a message-driven bean using the NetBeans wizard, the Server Destinations drop-down is blank. (see screenshot).
It should show the jms queue I created. I've tried restarting Wildfly and NetBeans, but to no avail. Can anyone advise a solution?

That certainly looks like a bug (or at least a relic from the Glassfish support code), you may want to file a bug report for that. But in the mean time, it's not hard to work around. Assuming you created (via the Wildfly console) a queue named testq with jndi name java:/jms/testq you can just enter jms/testq as a "Project Destination" in the wizard and it will work. This will lead to the following (minimal) code
#MessageDriven(activationConfig = {
#ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/testq")
,#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class SomeMessageBean implements MessageListener {
and the onMessage handler:
#Override
public void onMessage(Message message) {
}
You could as well create a regular class and add the #MessageDriven annotation, there's really nothing magical about mdb's

Related

properties file is not created at first run when server starts

I am working with Java 8 application. I am trying to create a file. When I deploy the war in jboss 10 server and start it, file is not generated. At second run file is generated. Can someone please help me over this? My code for file generation is:
File workletProps = new File(configDir, DBConstants.OfflineWorkletExportProperties.WORKLET_EXPORT_CONFIG_WORKLET_PROPERTIES.getGettypeValue() +".properties");
PrintWriter pw = new PrintWriter(workletProps);
pw.println("WORKLET_ID=" + worklet.getId());
pw.println("PROJECT_ID=" + worklet.getProject().getId());
pw.flush();
pw.close();
Please refer to Eager / auto loading of EJB / load EJB on startup (on JBoss) on how to execute code on JBoss startup. JBoss 10 (Wildfly 10) supports Java EE 7 which includes EJB 3.2, which should empower you to do the following:
#Singleton
#Startup
public class StartupBean {
#PostConstruct
private void postConstruct() {
// your file generation code here, enriche with exception handling and logging
}
If that does not work as you expect, set a break point and debug.
}

UnknownServiceException: Unknown service requested [EnversService]

I want to run Hibernate in OSGi. I have added the standard Hibernate OSGi bundle and a Blueprint implementation, so that Envers gets registered right on startup.
Even without any kind of documentation I found out you have to start Envers, because... I doubt there is a logical reason, it does not work otherwise.
However now, even though Envers was registered in Blueprint, I get the following exception:
org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.envers.boot.internal.EnversService]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:184)
at org.hibernate.envers.boot.internal.TypeContributorImpl.contribute(TypeContributorImpl.java:22)
at org.hibernate.boot.internal.MetadataBuilderImpl.applyTypes(MetadataBuilderImpl.java:280)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.populate(EntityManagerFactoryBuilderImpl.java:798)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:187)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:34)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:165)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:114)
at org.hibernate.osgi.OsgiPersistenceProvider.createEntityManagerFactory(OsgiPersistenceProvider.java:78)
at org.acme.project.Main.startSession(PersistenceUnitJpaProvider.java:38)
The stack trace starts at PersistenceProvider#createEntityManagerFactory in the following snippet:
public class Main {
private EntityManagerFactory entityManagerFactory;
public void startSession(Map<String, Object> config) {
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
ServiceReference<PersistenceProvider> serviceReference = context.getServiceReference(PersistenceProvider.class);
PersistenceProvider persistenceProvider = context.getService(serviceReference);
this.entityManagerFactory = persistenceProvider.createEntityManagerFactory("persistenceUnit", config);
context.ungetService(serviceReference);
}
I found this bug, and maybe this issue is fixed in the current version of Hibernate. But since the bundle IDs are broken, I have to use 5.1.
So Envers is registered, but not really. What could be the reason for such a strange error message?

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;

Glassfish: JTA/JPA transaction not rolling back

I am running Glassfish 3.1.1 with an Oracle database and have run into an issue with transactions not rolling back, but only on one specific environment so far. The same application works as expected on other machines. However, two separate Glassfish domains on the same machine are impacted.
Within the affected environment, I have similar results with both a container-managed transactions (CMT) inside an EJB that throws a RuntimeException, and a bean-managed transaction (BMT) with UserTransaction#rollback().
In both cases, the underlying issue appears to be that the JDBC connection is somehow still set with autoCommit = true even though there is a JTA transaction in progress.
My EJB/CMT test looks like this:
#Named
#Stateless
public class TransactionTest {
#PersistenceContext
EntityManager entityManager;
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void rollbackTest() {
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
throw new RuntimeException("should be rolled back");
}
}
and my BMT/UserTransaction test is like this:
public void rollbackUtxTest() throws Exception {
utx.begin();
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
utx.rollback();
}
When I call either method, the INSERT INTO FOO is committed, even though the transactions were rolled back.
What am I missing - perhaps I don't have my connection pool / datasource is not set up right?
I'm using OracleConnectionPoolDataSource as the datasource class name. Is there something I need to do to ensure my database connections participate in JTA transactions?
UPDATE 1 I originally thought this was an issue with OracleConnectionPoolDataSource but it turned out it was not correlated. The same exact pool configuration works on one environment but not the other.
UPDATE 2 Clarified that this is not specifically an EJB/CMT issue, but a general JTA issue.
UPDATE 3 added info about JDBC autocommit. Confirmed that persistence.xml is correct.
It looks like this may be an issue with domain.xml, possibly a Glassfish bug.
In persistence.xml, I have
<jta-data-source>jdbc/TEST</jta-data-source>.
In domain.xml, I have
<jdbc-resource pool-name="TEST_POOL" description="" jndi-name="jdbc/TEST"></jdbc-resource>
But no corresponding <resource-ref ref="jdbc/TEST"> - either missing or misspelled. (I believe I ended up in that state by creating the JNDI datasource through the UI, realizing the name is wrong, then fixing the JNDI name in domain.xml jdbc-resource by hand but not fixing it in resource-ref.
In this case, my injected EntityManager still works but is not participating in JTA transactions. If I fix domain.xml, it works as expected.
You didn't wrap your Exception in an EJBException.
See http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html

Configuring one ear to call remote ejb3 on another ear in JBoss

I am new to EJB3 and am missing something when it comes to accessing a #Remote #Stateless bean deployed as an ejb module inside an ear file. I want to access a remote bean in lima.ear from soup.ear.
Here is what I am doing now (somewhat abbreviated):
//deployed under lima.ear
#Remote
#Stateless
public interface LimaBean {
String sayName();
}
I want to put LimaBean in the Soup:
//deployed in soup.ear
#Stateless
public class Soup implements SoupLocal {
#EJB
private LimaBean limaBean;
public String taste() {
return limaBean.sayName();
}
}
When I start JBoss I get the following error:
java.lang.RuntimeException: could not resolve global JNDI name for #EJB for container Soup: reference class: com.example.LimaBean ejbLink: not used by any EJBs
I have had a hard time finding out what this ejbLink is about, if that is the right path to go down.
If I deploy LimaBean as a jar file in jboss then everything works great!
I ran accross an article that had a section called "2.5.3. References between beans in different jars and different ears"
(http://jonas.ow2.org/doc/howto/jboss2_4-to-jonas3_0/html/x111.html)
Example of jboss.xml file for SB_BrowseRegions:
<jboss>
<session>
<ejb-name>SB_BrowseRegions</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/Region</ejb-ref-name>
<jndi-name>protocol://serverName/directory/RegionHome</jndi-name>
</ejb-ref>
</session>
</jboss>
If I touch the soup.ear, after JBoss starts up then it deploys fine, so I am assuming I need to specify a dependency like the above article says.
But even after it deploys then I get an error when accessing the remote LimaBean:
Caused by: java.lang.IllegalArgumentException: Can not set com.soup.LimaBean field com.soup.Soup.limaBean to $Proxy147
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at org.jboss.injection.JndiFieldInjector.inject(JndiFieldInjector.java:115)
... 49 more
I have tried a few things but, if anyone can point me in the right direction about this I would appreciate it.
It looks like the JNDI properties need to be set as if it were a remote client outside of the app server because of the ear isolation we have setup.
properties.put(Context.PROVIDER_URL, url);
InitialContext ctx = new InitialContext(properties);
Just specify the URL for the InitialContext and that should do the trick.