How can I deploy a resource-adapter activation in JBoss 7? - maven

I am trying to figure out how to deploy a resource-adapter activation in JBoss 7. Basically, I want to be able to package and deploy a full application without having to modify the base server configuration, in part because I want to bootstrap testing using Arquillian but also because I want to be able to deploy my packages into an environments where I may not have the option of modifying the base server's configuration.
Here's where I am right now. I have created an EAR which contains the active-mq rar (which is also configured in the application.xml). This ear by itself builds and deploys perfectly using the maven ear plugin and the jboss-as-maven-plugin.
However, in order to activate the rar, the only way I have been able to figure out is to hack the rar file itself and add an ironjacamar.xml into the rar's META-INF directory. But in order to do this, I had to hack the rar in my maven repo which I don't really want to do.
I tried to get maven to add the ironjacamar.xml during the packaging phase of my maven pom, but that's a bit of hack as well and I couldn't get it work anyways. (Note to self: check on Deployment Overlays)
I also thought about scripting the addition of a connection-factory using jboss-cli, but the docs clearly state that is for creating factories for the built in hornet-mq server which is not my target, and swapping the default JMS implementation in the server requires some major surgery on the server's config.
I looked though all the quickstart projects and observed all sorts of constructs being deployed though -jms.xml and -ds.xml files included in the package, but they're also specific to hornet-mq and JDBC respectively. (I was hoping the deployer might support a -rar.xml or the like).
The only other way I can think of, and I don't know if it is supported, is to define a subsystem deployment in my package. Is there such a thing ?
===== UPDATE =====
I tried adding a cli overlay update (as I would using the maven jboss as plugin) but it had no effect.
deployment-overlay add --name=rarActivation --content=META-INF/ironjacamar.xml=\..\container\src\main\resources\ironjacamar.xml --deployments=activemq-rar.rar --redeploy-affected

Well, in the absence of any other answers, this is the solution I came up with. It's a bit of a hack, but it has worked flawlessly with Active MQ and WebSphere MQ. The premise is that I deploy 2 different RARs per JMS system I want to connect to. One is the untouched xxx.rar file I retrieve from the Maven repository. The second is my "configuration RAR" which contains a copy of the ra.xml from the original rar, and then an ironjacamar.xml configuration file. Both of those are placed in the config rar's META-INF folder.
For each given vendor RAR, the ironjacamar.xml file can be generated using rar-info.sh which is included in the Iron Jacamar 1.1 download. The procedure is described in the section titled 10.1. Resource adapter information tool int the user guide.
Using ActiveMQ 5.8.0 as an example:
The generated ironjacamar.xml is extracted from the full output of the rar-info.sh output. Within the file, it is titled:
Deployment Descriptor:
----------------------
The extracted part of the file that will become ironjacamar.xml starts after that header and ends with </resource-adapters>.
The following edits should be applied:
Remove the opening <resource-adapters> and <resource-adapter> tags and replace with an <ironjacamar.xml> opening tag.
Remove the opening <archive> tag.
Remove the closing </resource-adapter> and </resource-adapters> tags and replace with an </ironjacamar.xml> closing tag.
There are sample definitions for connection factories for each type of connection (Connection, Queue and Topic) which include a JNDI name where JBoss will bind the factories to. Edit these as you see fit. I only needed the Connection factory so I edited the JNDI name and deleted the other two definitions.
There are sample definitions for destination references (which are almost un-necessary with ActiveMQ, but it's helpful for others). One for a queue, one for a topic. Edit these as you see fit.
The maven dependency:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-rar</artifactId>
<version>5.8.0</version>
<type>rar</type>
</dependency>
The deployable EAR looks like this:
sample.ear
META-INF
application.xml
activemq-rar.rar (file)
activemq-config.rar (directory)
ra.xml (extracted from activemq-rar.rar or generated)
ironjacamar.xml (generated, then edited)
Actually, the ra.xml can be extracted from the "real" rar, but it is also generated in the IronJacamar rar-info.sh output file, so take it from either.
The application.ear then looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<display-name>JBoss7Sample Ear</display-name>
<!-- Sample for WebSphereMQ
<module><connector>wmq.jmsra.rar</connector></module>
<module><connector>wmq-config.rar</connector></module>
-->
<module><connector>activemq-rar.rar</connector></module>
<module><connector>amq-config.rar</connector></module>
</application>
To re-emphasize, this (actually quite simple) work around is important to me because any deployment procedure that starts with "Edit the server file called..... or "In the management console....." is a non-starter in the environment I am targeting. I need to assume no access to a vanilla JBoss 7 (EAP 6.1) internal directories, nor access to the console, as one might deploy at the end of a Jenkins build or the like.. (Not to mention which, editing files to add a deployment is a non-starter all by itself).
This workaround and others can be viewed in more detail in this github project which was setup specifically to share some working configurations which I have found are otherwise fairly difficult to come by.
P.S. Since this is the only offered answer, I am awarding the correct answer to myself, but I'll give it up for a better answer.

Related

Set Parent_Last on websphere 9

While using Websphere 7, I had in my EAR a nice little file called deployment.xml which told my WAS server to configure the deployment to PARENT_LAST. I had this file at
/MyEAR/META-INF/ibmconfig/cells/defaultCell/applications/defaultApp/deployments/defaultApp/deployment.xml
When moving to Websphere 9, it appears it is no longer honoring this directive. I go to the admin console and can see it thinks the EAR is deployed with PARENT_FIRST under "Class loading and update detection"
here is the text of the xml
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi">
<deployedObject startingWeight="10" warClassLoaderPolicy="SINGLE" xmi:type="appdeployment:ApplicationDeployment">
<modules startingWeight="10000" uri="Provider_lfcPractice_ImplWeb.war" classloaderMode="PARENT_LAST" xmi:type="appdeployment:WebModuleDeployment"/>
<classloader mode="PARENT_LAST"/>
</deployedObject>
</appdeployment:Deployment>
Is there still a way to configure the EAR to deploy the war with PARENT_LAST in websphere 9?
This should still work. Check this Select installation options settings, it talks about the deployment.xml
Process embedded configuration
Specifies whether the embedded configuration should be processed. An
embedded configuration consists of files such as resource.xml,
variables.xml, and deployment.xml.
So make sure that that checkbox is selected, as it is off by default. Also if you are deploying via wsadmin script, make sure that you are using that option.
The other way, would be to select all the options after installation that you require, export that ear and compare it to the one that you are installing.
With Gas's comment it was clear it should work. What happened to me is that I had added maven nature to the EAR at one point. Bad idea. Even though I had already removed the maven nature, it corrupted the file
org.eclipse.wst.common.component
It was missing the line
<wb-resource deploy-path="/" source-path="/"/>
When I added that line back, my deployment.xml file began working as expected

How can I include a resource file (logback.xml) in a project when building JAR but not when embedded in a WAR?

I'm working on a project that uses two maven projects (named core and webapp); core is built with JAR packaging and used for two different purposes: as a stand-alone app (essentially an executable JAR), and also embedded into webapp.
For its purpose as a stand-alone app, core needs to have its own logback configuration (a logback.xml file) that needs to be included on the classpath. Normal Maven convention would have me put it in src/main/resources/logback.xml. That works fine, but causes a problem when the core JAR is included in webapp. webapp needs to have its own logback configuration, but the container (tc Server or Jetty) is picking up the one from core.jar first.
I realize that logback can be told about a custom config location via a system property (-D on the command line) but that's not viable in a app container like Tomcat or Jetty.
I've read some other people asking about this situation, but none of the solutions I've seen sits well with me. One solution involved setting up a context listener that runs early in the webapp initialization and explicitly configures logback based on a <context-param>. That's a bit brutish in my opinion, and probably a hard sell to my fellow dev team when log4j "just works" in this situation.
I'm far from a Maven expert, so I'm hoping there is some elegant way to get Maven to help me here. Or perhaps some logback extension or add-on that makes it more web-app friendly. Or even a clever idea that I haven't thought of.
There are a number of possible solutions, but the easiest is to put the file in its own module and mark the dependency as provided. The, conspire to have it on the classpath when running the standalone version of the app.
The solution that we ended up using was to leave only the common "non-app" pieces (code and configuration) in core and then extract the other "app" pieces into a new module (batch-app).
The logging configuration only lives in the 2 app projects (webapp and batch-app) that depend on core. core has a logback-test.xml configuration in it, but that's excluded from the JAR that maven builds (since it's in the src/test/resources folder).

Externalizing static content from a WAR and serve both on jetty

In my project I use Maven to package a web application to a WAR which is later deployed to Jetty using a custom Maven plugin on CentOS. The custom plugin is used by every project that deployes to a production environment. There is now a requirement that all static content (like web site text, properties) is packed outside of the WAR so that it can be changed in production without requiring a new release cycle. I am unsure how to achieve this externalization.
The Jetty server has the directory structure described in Jetty quick start guide. Currently, the web application already offers some .properties files which can be altered externally, and these reside in the resources/ directory. These files are moved here by the custom Maven plugin. The WAR resides in the webapp/ folder. One option for my problem is to use <packagingExcludes> of maven-war-plugin to not include e.g. *.xhtml and *.properties in the WAR. Later, I can use the custom Maven plugin to move excluded files to resources/ directory. But, I have a feeling this is not the correct way to externalize static content... Shouldn't xhtml files live in webapp/ folder while the only the properties file live in resources/ folder?
I have also researched the option of deploying the WAR as exploded, but I am unsure of the implications of such. Clearly, the changes in the exploded WAR files will be overwritten in the next deploy, but the idea is to do static changes both in development and production. Also, I am not sure how to achieve WAR "explosion", is it something that Jetty does for your WAR if configured in jetty.xml or do I have to extract the WAR before deploying?
Lastly, how do people serve static content in Jetty which can be altered in production? Do both the WAR and static files live side by side
The Jetty resources folder should not be used for application files. A J2EE web application (war) should be self-contained -- and in Jetty, reside only on the /webapps folder -- and its only binding to the container (Jetty servlet engine) is via the web.xml deployment descriptor.
Since property files may be read from the classpath and the Jetty resources folder is part of the system classpath, a property file there could be read by the web application class loader. Note that there are other ways to read property files as well and the Jetty resources folder should not be used for application properties. Also, the application may not be portable as other application servers have different forms of webapp classloader isolation.
If the below architecture approach does not work for you, then your only approach would be to expand (explode the war) in the /webapps folder and hope for the best when files are edited.
Tackling this from a different angle,
- if your web application depends on .properties and .xhtml files in order to function properly, then these files are probably not 'content'. The fact that there is a business process that requires them to to be updated ad hoc does not make them content.
- 'content' is something like text, images, and videos that is added, edited and removed by an administrative user. The application does not depend on it for correct execution, it merely reads and passes it on the browser.
Suggestions:
I would suggest that you deploy your application every time there is a change to the .xhtml or .properties files change. If the editors of these files are power business users, you might think of a git push-pull tool for them and a continuous build hook, so that when they make changes and push them to the git repository, the application gets tagged with a newer version and gets built and deployed. If there is a problem (tag not closed in xhtml), then it would be easy to roll back to the last tag.
Alternately, if the changes are minor (such as text descriptions), then modify the application to read them from an arbitrary external file (outside the webapp) -- a location that is provided to the webapp on startup. You can then package a 'default' version of the file in the webapp, but the code would attempt to look in the specified external location first.
I discovered that you can add HTML tags to properties and later use <h:outputFormat> to fetch these properties with parameters. Also, you can do pretty neat stuff with property files as described in MessageFormat API.
My solution was to keep the .xhtml files inside the WAR, but use simple HTML snippets properties from the default resource bundle which is based on a .properties file. These properties were included in the .xhtml using <h:outputFormat>and <h:outputText>. This allows the user to add simple styling like bold and underline to the snippets.
The properties file are copied to the Jetty resource folder using the custom Maven plugin, so I have kept the .properties files in the WAR. For some reason the Jetty resource folder has precedence over the packed .properties files, so this works out fine. Also, as Akber pointed out, I will have the default versions of the properties available if for some reason the WAR was moved to some other application server where the resource folder is not available.
Of course, with this approach the code can break if malformed HTML is placed inside the snippet properties, as pointed out by Akber, but it works for our application as it is very small. I may never have done this if this was a much larger application, but then I might have gone for a database based solution for adding static text (like Joomla/Drupal/Wordpress).

Roles not being correctly configured when migrating Enhanced EAR from WAS6.1 to WAS8

I have an enhanced ear with ibm-application-bnd.xml defined as
<?xml version="1.0" encoding="UTF-8"?>
<application-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-bnd_1_0.xsd"
version="1.0">
<security-role name="myRole">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
This myRoleis also defined in the WAR web.xml. The mapping between the role and ALL_AUTHENTICATED_USERS worked fine in WAS6.1, but in WAS8 after I deploy de EAR I can see in "Security role to user/group mapping" that myRole Special Subjects mapped as none. I have to manually map the special subjects to "All Authenticated...".
I've tried creating an ibm-application-bnd.xmi instead, but I'm currently not using RAD and have no idea if it's possible to do it in eclipse, since it has these generated ids like ApplicationBinding_1332889227228 that I don't know how to fill!
Basically it may be a good idea to (1) deploy your EAR manually and set up all missing config data during this process as needed, and (2) have a look on the descriptor files generated by WAS8 afterwards. At least when moving from 4 to 5 and later on to 6 we used this "technique" to figure out how ready-to-go vendor-specific descriptors should look like. It may be necessary to strip off all pre-prepared vender-specific descriptors before executing this step.
2 Additional hints:
(a) WAS8 documentation says that WAS8 supports all previous J(2)EE standards, but generally XMI files are deprecated and should be replaced by XML files. But the "id problem" remains, since WAS8 also refers from vendor-specific files to standards compliant files by element IDs used in URL-like references. Thus any deployment of un-prepared EARs will create IDs inside the Java EE standard descriptors.
(b) It may be useful to do some research about the "new" name of your special subject: It looks like this name has simply changed from 6.1 to 8.x. For this purpose you also should take a closer look at the generated descriptor files after a successful manual EAR deployment.

xmlaccess deploy portlet with library reference

I have problem with deploying JSR168 portlet using xmlaccess. I have no problem with deploy and join to conrete page but I would like to add shared library reference automatically. Is it possible?? I added shared library named 'libshared' using IBM WS console. Can I add this reference in input xml using by xmlaccess?
I don't think you can do this in xmlaccess. But you may try putting a reference to the library under the Manifest.MF file of the META-INF directory of your portlet's war file.
Or could just put the shared jar file under your /shared/ext directory. Or you could put it inside your wps.ear file. Mind you, either of these two solutions would share your library with the entire portal installation, rather than just select portlets.
You can deploy the application using wsadmin or similar and use that to update the classpath (i.e. for the shared library), you can then use xmlaccess to deploy the portlets and reference the previously deployed application - although I think this may only work in WebSphere Portal 6.1.
Give me a shout if you need further details.
I encountered this as well, a while ago... and researched it to the max, including spending some time chatting with IBM's support in various levels.
The XMLAccess protocol doesn't provide for such "system-level" configuration alongside Portlet application deployment; it can only be used to install, customize and uninstall Portlet applications and related artifacts.
If your deployment strategy involves deploying WAR files directly through XMLAccess, then you will have to manually add the shared-library to the application through the WAS admin console; this will have to be done manually because, when deploying WAR files through XMLAccess, an EAR with some random name is being created by WebSphere Portal to "host" your WAR file; hence you can't script the attachment of a shared library.
(alternatively, you may wish to add the shared library to the server's (WebSphere_Portal) classpath)
If your deployment strategy, instead, involves deploying Portlet applications packaged as EARs, then you're in a better position; you could automate the shared-library attachment as part of your EAR deployment process, then use XMLAccess to inform WebSphere Portal about the location, in the EAR, of your Portlet applications (which is what Michael mentioned above; it works in WebSphere Portal 6.0 as well).
Good luck.

Resources