Posts Tagged ‘jboss’

Tomcat query parameters and encodings

Did you ever wondered which from which encoding the query parameters are parsed by default in java (servlet) and the response in rendered? Say UTF-8. Wrong. Try ISO-8859-1. There are 3 cases to consider:

1. Query parameters as GET

2. Query parameters as POST

3. Response encoding. (more…)

JBoss migration 4.2.2-GA to 5.1.0-GA

In my stupidity innocence I just hoped that deploying the application on the new JBoss (from 4.2.2-GA to 5.1.0-GA) should be just a simple matter of changing paths in ant. Here are some problems I encountered and was able to fix. (more…)

JBoss and LDAP

Target: create a test environment for JBoss JAAS authentication using LDAP.

Platform: Linux Ubuntu 9.10, JBoss 4.2.2.GA, java 1.6.0_15

Install and configure openldap

Installing ldap proved to be the most complicated part as apparently Karmic stripped all ldap configuration from the install so all tutorials found on ubuntu site are useless. Finally I’ve found a thread which described the process. Here are the steps I followed: (more…)

Secure JBoss JMX Console

Since JBoss can now be installed from a zip file it comes with a default unsecured jmx-console. This is unacceptable for production so here is the method to secure the jmx-console using http authentication (applies to JBoss 4.2.2.GA).

1. Edit jboss/server/default/deploy/jmx-console.war/WEB-INF/web.xml and uncomment the security-constraint element:

   <security-constraint>
     <web-resource-collection>
       <web-resource-name>HtmlAdaptor</web-resource-name>
       <description>An example security config that only allows users with the
         role JBossAdmin to access the HTML JMX console web application
       </description>
       <url-pattern>/*</url-pattern>
       <http-method>GET</http-method>
       <http-method>POST</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>JBossAdmin</role-name>
     </auth-constraint>
   </security-constraint>

2. Edit jboss/server/default/deploy/jmx-console.war/WEB-INF/web.xml and uncomment the security-domain element:

<security-domain>java:/jaas/jmx-console</security-domain>

3. Edit jboss/server/default/conf/login-config.xml and make sure that you have the definition of the jmx-console authentication-policy

<application-policy name = "jmx-console">
       <authentication>
          <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
             flag = "required">
           <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
           <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
          </login-module>
       </authentication>
</application-policy>

4. Edit the files jboss/server/default/conf/props/jmx-console-users.properties and jboss/server/default/conf/props/jmx-console-roles.properties to edit your users.

Another way to use Quartz in JBoss

I was explaining here how to create a Quartz job using the standard Quartz-ra service which comes bundled with JBoss. The method is rather limited, or I was not able to find the proper documentation on how to register new jobs on the fly. This is why in this post I will show how to access the quartz scheduler directly. (more…)

Creating a Quartz job

In new versions of JBoss (such the 4.0.5 which I am using) there is a quartz-ra.sar service which should allow me to define some a job with a cron like specification.

Searching the forums and the jboss site I was able to put together quickly an example:

import org.jboss.annotation.ejb.ResourceAdapter;import org.jboss.logging.Logger;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;

import javax.ejb.MessageDriven;import javax.ejb.ActivationConfigProperty;

@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0/2 * * * * ?") })

@ResourceAdapter("quartz-ra.rar")

public class Test implements Job {    private static final Logger log = Logger.getLogger(Test.class);

    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        log.info("executing Test job");    }}

I packed this into a jar and deployed to jboss and was able to see the “executing Test job” message each 2 seconds.

Next step was to externalize the cronTrigger property to an external file such that the property is not hardcodded in the configuration file. This proved to be a very complicated issue since I could find absolutely no example. After 3 hours of searching I was able to put together a working example. Here are the files:

The java file:

import javax.ejb.EJBException;import javax.ejb.MessageDrivenBean;import javax.ejb.MessageDrivenContext;import javax.jms.Message;import javax.jms.MessageListener;

import org.jboss.logging.Logger;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;

/*MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0/2 * * * * ?") }) ResourceAdapter("quartz-ra.rar")*/public class Test implements Job, MessageDrivenBean, MessageListener {	private static final Logger log = Logger.getLogger(Test.class);

	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {		log.info("executing Test job");	}

	/**	 * @see javax.ejb.MessageDrivenBean#ejbRemove()	 * @throws EJBException	 */	public void ejbRemove() throws EJBException {	}

	/**	 * @see javax.ejb.MessageDrivenBean#setMessageDrivenContext(javax.ejb.MessageDrivenContext)	 * @param context	 * @throws EJBException	 */	public void setMessageDrivenContext(MessageDrivenContext context) throws EJBException {	}

	/**	 * @see javax.jms.MessageListener#onMessage(javax.jms.Message)	 * @param message	 */	public void onMessage(Message message) {	}

	public void ejbCreate() {		log.info("Test job created");	}}

The ejb-jar.xml file:

<?xml version="1.0" encoding="UTF-8"?><ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee         http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">    <enterprise-beans>        <message-driven>            <ejb-name>Test</ejb-name>            <ejb-class>Test</ejb-class>            <messaging-type>org.quartz.Job</messaging-type>            <transaction-type>Container</transaction-type>            <activation-config>                <activation-config-property>                    <activation-config-property-name>cronTrigger</activation-config-property-name>                    <activation-config-property-value>                        <![CDATA[0/2 * * * * ?]]>                    </activation-config-property-value>                </activation-config-property>            </activation-config>        </message-driven>    </enterprise-beans></ejb-jar>

The jboss.xml file:

<?xml version="1.0" encoding="UTF-8"?>

<jboss>   <enterprise-beans>      <message-driven>         <ejb-name>Test</ejb-name>         <destination-jndi-name>dummy</destination-jndi-name>         <resource-adapter-name>quartz-ra.rar</resource-adapter-name>      </message-driven>   </enterprise-beans></jboss>

A short list of links which proved usefull:

Does Date() returns localtime?

Getting the correct date and time was always a problem but I could not expect it’s still a problem on today java and OS versions.

Trying to deploy a JBoss on various Linux and JBoss I could not notice that on each system the date in the log was different from the localtime. Initially I thought it’s just a JBoss configuration problem but a simple example shows it’s not:

import java.util.Date;

public class TestDate {
public static void main(String[] args) {
System.out.println("Current date is: " + new Date());
}
}
len@black:$ java TestDateCurrent date is: Tue Jul 03 14:55:03 GMT+02:00 2007

len@black:$ dateTue Jul  3 15:55:13 EEST 2007

len@black:$ java -versionjava version "1.5.0_11"Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)Java HotSpot(TM) Server VM (build 1.5.0_11-b03, mixed mode)

After running this on various systems from linux to solaris the results where completely haotic. It took some digging to find a solution for the problem but finally it was rather simple.

java -Duser.timezone=Europe/Bucharest TestDate
java -Duser.timezone=$(cat /etc/timezone) TestDate

Apparently java needs some confirmation of the timezone it’s in in order to display the date correctly.

JBPM Hibernate cache

Applies to: JBPM 3.1.2, JBoss 4.0.5-GA

Everything starts with a beautiful concept but has to pass past those nasty errors. The same applies to this JBPM project, everything was nice, I have seen it running and then I was supposed to take the sources, clean, organize and enhance. Everything ok until now. The only problem is that when deploying the JBPM (sar) service there was this error:

16:09:17,402 ERROR [CommandExecutorThread] org.hibernate.HibernateException: Could not instantiate cache implementation

(more…)

Webapp logging

Applies to: JBoss 4.0.5 GA

Everything started with a web application which worked perfectly inside a Tomcat 5 container and had to be migrated to JBoss. At the first deployment got this error:

14:45:56,496 ERROR [STDERR] log4j:ERROR The class "org.apache.log4j.spi.ErrorHandler" was loaded by 14:45:56,496 ERROR [STDERR] log4j:ERROR [WebappClassLoader  delegate: false  repositories:    /WEB-INF/classes/----------> Parent Classloader:java.net.FactoryURLClassLoader@172bab9] whereas object of type 14:45:56,497 ERROR [STDERR] log4j:ERROR "org.jboss.logging.util.OnlyOnceErrorHandler" was loaded by [org.jboss.system.server.NoAnnotationURLClassLoader@19616c7].14:45:56,542 ERROR [STDERR] log4j:ERROR Could not create an Appender. Reported error follows.14:45:56,542 ERROR [STDERR] java.lang.ClassCastException: org.jboss.logging.appender.DailyRollingFileAppender

After searching the forums for a while I found this link according to which all I had to do is:

export JAVA_OPTS=-Dlog4j.defaultInitOverride=true

This solved indeed the error and I was quite happy to see the application running but I soon realised that in fact this fixed the problem as the error did not occured anymore but the log mechanism did not worked either.

After a lot more search I finally found the JBoss recomandation for this problem: all I had to do is to remove the log4j and commons-logging jars from the war file:

<war warfile.......<lib dir="${lib.dir}">	<include name="*.jar" />	<exclude name="log4j*.jar" />	<exclude name="commons-logging*.jar" /></lib>

JMX invocation with secured console

Applies to: JBoss 4.0.5 GA

As I am working on a rather complex application with a lot of dependancy bounded MBeans I found it necessary to have a small application, in a different JVM, invoke a MBean method for administrative purposes. Even if this sounded easy at the begining it seemed that I had to face 2 problems:

  • JBoss JMX implementation
  • JAAS access to the secured console

Since I both googled and searched JBoss forums without much help I decided, upon succeding, to write this article as it might help someone futher.

The ideea was to get access to a MBean service with the name:

ro.nit.test:service=Test

and to be able to get it’s “Message” attribute and also invoke a remove method called: “printMessage”. The jmx-console was protected with admin/simple

The working code is:

AppCallbackHandler handler = new AppCallbackHandler("admin", "simple".toCharArray());
LoginContext lc = new LoginContext("TestClient", handler);
System.out.println("Created LoginContext");lc.login();

Hashtable env = new Hashtable();
String factory = "org.jnp.interfaces.NamingContextFactory";
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
String url1 = "jnp://localhost:1099";env.put(Context.PROVIDER_URL, url1);
env.put(Context.SECURITY_CREDENTIALS, "simple");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_PROTOCOL, "testLoginInitialContext");
Context ctx = new InitialContext(env);
MBeanServerConnection mconn = (MBeanServerConnection) ctx.lookup("jmx/invoker/RMIAdaptor");
ObjectName name = new ObjectName("ro.nit.test:service=Test");
Object val = mconn.getAttribute(name, "Message");
System.out.println(name + "\n\tmessage=" + val);
mconn.invoke(name, "printMessage", null, null);

This makes use of the following CallbackHandler implementation:

static class AppCallbackHandler implements CallbackHandler {
private String username;
private char[] password;

public AppCallbackHandler(String username, char[] password) {
	this.username = username;
	this.password = password;
}

public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException {
	for (int i = 0; i < callbacks.length; i++) {
		if (callbacks[i] instanceof NameCallback) {
			NameCallback nc = (NameCallback) callbacks[i];
			nc.setName(username);
		} else if (callbacks[i] instanceof PasswordCallback) {
			PasswordCallback pc = (PasswordCallback) callbacks[i];
			pc.setPassword(password);
		} else {
			throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
		}
	}
}
}

The “auth.conf” file required by JAAS:

other {
   // jBoss LoginModule   org.jboss.security.ClientLoginModule  required   ;
   // Put your login modules that need jBoss here};

The JVM parameters:

-Djava.security.auth.login.config=file:${path to file}/auth.conf

Links with helped me found the solution:

  • http://www.jboss.com/index.html?module=bb&op=viewtopic&t=95530&view=previous
  • http://www.jboss.org/index.html?module=bb&op=viewtopic&t=84303
  • http://www.jboss.org/index.html?module=bb&op=viewtopic&t=83861

Some errors which I got on the way:

  • Exception in thread “main” java.lang.SecurityException: Failed to authenticate principal=null, securityDomain=jmx-console

The original code (according to JSR160):

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8080/jmx-console");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName stdMBeanName = new ObjectName("ro.nit.test:service=Test");
mbsc.setAttribute(stdMBeanName, new Attribute("Message", "New message set from remote"));
// TODO, will not work with JBOSS since it does not implement the
// JMX properly
// http://www.jboss.com/index.html?module=bb&op=viewtopic&t=95530&view=previous
Related Posts with Thumbnails