JBoss/JAAS Configuration Error: Encountered "<?xml" at line 1, column 1

Recently, I upgraded my JBoss installation to 4.2.3.GA and encountered problems with my existing login configuration files.

The following error was generated on server startup:

18:27:32,171 WARN  [ServiceController] Problem starting service jboss:service=DynamicLoginConfig
org.jboss.security.auth.login.ParseException: Encountered "<?xml" at line 1, column 1.
Was expecting one of:
    <EOF>
    <IDENTIFIER> ...
   
at org.jboss.security.auth.login.SunConfigParser.generateParseException(SunConfigParser.java:395)
at org.jboss.security.auth.login.SunConfigParser.jj_consume_token(SunConfigParser.java:333)
at org.jboss.security.auth.login.SunConfigParser.config(SunConfigParser.java:98)
        ...

It was complaining about a parsing error on the first line of my login config file which was:

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE policy PUBLIC
      "-//JBoss//DTD JBOSS Security Config 3.0//EN"
      "http://www.jboss.org/j2ee/dtd/security_config.dtd">

<application-policy name = "TestRealm">
  <authentication>
    <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
           flag = "required">
    <module-option name = "unauthenticatedIdentity">guest</module-option>
    <module-option name = "dsJndiName">java:/testDS</module-option>
    <module-option name = "principalsQuery">select password from users where username=?</module-option>
    <module-option name = "rolesQuery">select r.name, 'Roles' from userroles ur, users u, roles r where u.userid = ur.userid and r.roleid = ur.roleid and u.username =?</module-option>
    </login-module>
  </authentication>
</application-policy>

The error message is misleading and caused me to waste time digging around the net finding dozens of people who had the same problem.

The actual problem with my file was it did not conform to the DTD which states:

The outline of the application-policy is:
<policy>
<application-policy name="security-domain-name">
  <authentication>
    <login-module code="login.module1.class.name" flag="control_flag">
      <module-option name = "option1-name">option1-value</module-option>
      <module-option name = "option2-name">option2-value</module-option>
      ...
    </login-module>

    <login-module code="login.module2.class.name" flag="control_flag">
      ...
    </login-module>
    ...
  </authentication>
</application-policy>
</policy>

My file was missing the enclosing <policy>...</policy> tags.