WebLogic 12c not obeying "prefer-web-inf-classes" or "prefer-application-packages" during deployment - deployment

I am having a very strange problem with WebLogic 12.1.3.0.0. I have an application that causes a NullPointerException inside the AdminServer during deployment, yet the application runs fine after the error.
The NullPointerException during deployment happens because the deployment process is not respecting the following settings in my deployment descriptors:
AppName.war/WEB-INF/weblogic.xml:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app>
<context-root>AppName</context-root>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
And AppName.ear/META-INF/weblogic-application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application>
<prefer-application-packages>
<package-name>javax.faces.*</package-name>
</prefer-application-packages>
</weblogic-application>
Since these settings are ignored, javax.faces.webapp.FacesServlet class is loaded by the System Classloader (sun.misc.Launcher$AppClassLoader), from $WL_HOME/wlserver/modules/glassfish.jsf_2.0.0.0_2-1-20.jar, not from the WAR classloader. This eventually leads to the NPE due to some poorly written code in weblogic.servlet.internal.WebAnnotationProcessor, which assumes that javax.faces.webapp.FacesServlet will be annotated with #MultipartConfig, which it is not in glassfish.jsf_2.0.0.0_2-1-20.jar. The correct version of this class is located in AppName.ear/AppName.war/WEB-INF/lib/jsf-api-2.2.16.jar.
I have verified all of this by remote debugging the AdminServer, and by turning on Classloader Logging, which shows this:
GCL[61ba0535][AppName.ear#AppName.war] GCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[10d372cb][] FCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[10d372cb][] FCL.findClass(javax.faces.webapp.FacesServlet)>
GCL[75bc8d74][DomainLib] GCL.loadClass(javax.faces.webapp.FacesServlet)>
This issue makes it impossible to open the AppName Deployment in the Admin Console, b/c it always throw the error (with the aforementioned NPE in the logs):
The configuration for AppName is still being loaded from your last request, please wait a moment and retry.
In contrast to this, when I run the EAR in the server where it was deployed, exactly the same EAR works just fine. To prove that classloading is working properly, here's the log:
CACL[6eb4b4ad][AppName#AppName] CACL.loadClass(javax.faces.webapp.FacesServlet)>
CACL[6eb4b4ad][AppName#AppName] GCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[37ee3b94][AppName#AppName] FCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[37ee3b94][AppName#AppName] FCL.findClass(javax.faces.webapp.FacesServlet)>
GCL[3cc63f62][AppName#] GCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[770e8d03][] FCL.loadClass(javax.faces.webapp.FacesServlet)>
FCL[770e8d03][] FCL.findClass(javax.faces.webapp.FacesServlet)>
FCL[770e8d03][] FCL.matchesClassFilterList(javax.faces.webapp.FacesServlet): javax.faces. index : 0 end : 12>
FCL[770e8d03][] FCL.findClass(javax.faces.webapp.FacesServlet): Found match>
GCL[3cc63f62][AppName#] GCL.findClass(javax.faces.webapp.FacesServlet)>
GCL[3cc63f62][AppName#] GCL.findLocalClass(javax.faces.webapp.FacesServlet): Classpath in use: <LIST OF ALL JARS IN MY EAR>
GCL[3cc63f62][AppName#] GCL.findLocalClass(javax.faces.webapp.FacesServlet): not found>
CACL[6eb4b4ad][AppName#AppName] CACL.findClass(javax.faces.webapp.FacesServlet)>
CACL[6eb4b4ad][AppName#AppName] CACL.findClass(javax.faces.webapp.FacesServlet): About to loadClass>
CACL[6eb4b4ad][AppName#AppName] GCL.findClass(javax.faces.webapp.FacesServlet)>
CACL[6eb4b4ad][AppName#AppName] GCL.findLocalClass(javax.faces.webapp.FacesServlet): Classpath in use: <LIST OF ALL JARS IN MY WAR>
CACL[6eb4b4ad][AppName#AppName] GCL.findLocalClass(javax.faces.webapp.FacesServlet): Found class>
CACL[6eb4b4ad][AppName#AppName] GCL.defineClass(javax.faces.webapp.FacesServlet)>
I don't know how to fix this... Why is the AdminServer completely ignoring the deployment descriptors in my EAR, while the server that runs the EAR sets everything up properly?
Any ideas would be appreciated.

Related

Quarkus native build Random/SplittableRandom exception with Vert.x Redis Client

I am doing a native build of my Quarkus app and am hitting the UnsupportedFeatureException: Detected an instance of Random/SplittableRandom on a few Vertx Redis Client classes.
I am building using the docker container method:
./mvnw package -Dnative -Dquarkus.native.container-build=true
I have fixed some of the exceptions by including in the pom.xml:
<quarkus.native.additional-build-args>
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient
</quarkus.native.additional-build-args>
but am stuck on this one:
Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing
io.vertx.redis.client.impl.RedisClusterConnection.send(io.vertx.redis.client.Request)
Parsing context:
at io.vertx.redis.client.impl.RedisClusterConnection.send(RedisClusterConnection.java:117)
at io.vertx.redis.client.impl.BaseRedisClient.lambda$send$1(BaseRedisClient.java:45)
at io.vertx.redis.client.impl.BaseRedisClient$$Lambda$1711/0x00000007c1ea57e8.apply(Unknown Source)
I have tried adding
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.RedisClusterConnection
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.BaseRedisClient
and even
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.RedisReplicationConnection.send(io.vertx.redis.client.Request)
but the error persists.
I am fairly new to Java and very new to native building / GraalVM etc
Can anyone shed any light on what class I should add, please?
Thanks,
Murray
I believe we can propose a change to vert.x redis client to avoid the split random use. The randomness is there mostly to share the load across nodes. It is not used for any security related features. For this reason, a proposal to either round-robin would probably make more sense as a solution to this issue.
Ok, this seems to fix it:
EDIT: No it doesn't. See below.
<quarkus.native.additional-build-args>
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.RedisReplicationConnection
</quarkus.native.additional-build-args>
The full profiles section in the pom.xml looks like this, for anyone else new to all this.
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
<quarkus.native.additional-build-args>
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.RedisReplicationConnection
</quarkus.native.additional-build-args>
</properties>
</profile>
</profiles>
I have different errors now, so still not building, but at least this seems to fix that specific issue.
EDIT: The problem persists...
If I build with the pom as described above, ie:
<quarkus.native.additional-build-args>
--initialize-at-run-time=io.vertx.redis.client.impl.RedisSentinelClient\,io.vertx.redis.client.impl.RedisReplicationConnection
</quarkus.native.additional-build-args>
I now get:
Error: Classes that should be initialized at run time got initialized during image building:
io.vertx.redis.client.impl.RedisReplicationConnection
the class was requested to be initialized at run time
(from command line with 'io.vertx.redis.client.impl.RedisReplicationConnection').
So, I guess that is not the right class afterall.
If I remove that class from the list I revert to the Random exception.
(Showing more detail)
[1/7] Initializing... (3.7s # 0.10GB)
Version info: 'GraalVM 22.3.1.0-Final Java 17 Mandrel Distribution'
Java version info: '17.0.6+10'
C compiler: gcc (linux, x86_64, 11.3.0)
Garbage collector: Serial GC
4 user-specific feature(s)
- io.quarkus.runner.Feature: Auto-generated class by Quarkus from the existing extensions
- io.quarkus.runtime.graal.DisableLoggingFeature: Disables INFO logging during the analysis phase for the [org.jboss.threads] categories
- io.quarkus.runtime.graal.ResourcesFeature: Register each line in META-INF/quarkus-native-resources.txt as a resource on Substrate VM
- io.quarkus.websockets.client.runtime.DisableLoggingFeature: Disables INFO logging during the analysis phase for the [io.undertow.websockets] categories
[2/7] Performing analysis... [*] (14.1s # 3.37GB)
12,032 (89.58%) of 13,432 classes reachable
17,778 (59.65%) of 29,803 fields reachable
61,621 (57.16%) of 107,809 methods reachable
541 classes, 150 fields, and 2,655 methods registered for reflection
Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.vertx.redis.client.impl.RedisReplicationConnection.send(io.vertx.redis.client.Request)
Parsing context:
at io.vertx.redis.client.impl.RedisReplicationConnection.send(RedisReplicationConnection.java:111)
at io.vertx.redis.client.RedisConnection.send(RedisConnection.java:83)
at io.vertx.redis.client.impl.RedisReplicationClient.getNodes(RedisReplicationClient.java:183)
at io.vertx.redis.client.impl.RedisReplicationClient.lambda$connect$4(RedisReplicationClient.java:126)
at io.vertx.redis.client.impl.RedisReplicationClient$$Lambda$2203/0x00000007c1630f60.handle(Unknown Source)
at io.vertx.core.impl.future.FutureImpl$1.onSuccess(FutureImpl.java:91)
{etc}
I am beginning to think I have an error / issue in my code where I am using the Vert.x Redis Client. I am trying to narrow it down by trial and error.
Any other suggestions are most welcome.

KIE-Server Container Stuck at CREATING Status

I am running the kie-server-showcase docker image and attempting to run a very simple rule on it.
I start the container as so:
docker run -i -p 8080:8080 --name kie-server --mount type=bind,source=$HOME/.m2,target=/opt/jboss/.m2 jboss/kie-server-showcase:latest
I need to use a bind mount as I'm just using my local .m2 maven repository (for now) and this was the only way I could see to get the container to get a copy of it.
I have built a kjar in Eclipse via "maven clean" followed by "maven install".
Inside the kjar (.jar) I have:
META-INF which contains kmodule.xml and MANIFEST.MF, also a maven subfolder which has the group-id followed by artifact-id in subfolders, i.e. META-INF > maven > group > artifact. The artifact folder contains the pom and pom.properties (which then defines the GAV).
my drl and bpmn
To create the container on the kie-server I use a curl command:
curl -u 'admin:admin' -H "accept: application/xml" -H "content-type: application/xml" -d #myContainer.xml -X PUT http://localhost:8080/kie-server/services/rest/server/containers/MyContainer
It then begins running the command but the time spent continues to tick on and was still going after I had left it for 30 minutes.
I checked the kie-server containers and the one I have added is there but the status is CREATING:
<response type="SUCCESS" msg="List of created containers">
<kie-containers>
<kie-container container-id="MyContainer" status="CREATING">
<release-id>
<artifact-id>hummingbird.rules.syndicated-kjar</artifact-id>
<group-id>uk.co.cdl.hummingbird</group-id>
<version>0.0.1-SNAPSHOT</version>
</release-id>
<scanner status="DISPOSED"/>
</kie-container>
</kie-containers>
</response>
I'm not very experienced with docker or using the kie-server, and in the past have not used kjars but had a custom rules engine that has loaded the drl and bpmn individually.
I believe it may be down to my kjar not being correct in some way. The docker container seems to see the kjar in the local maven repo mount (as I was previously getting errors that it couldn't find it).
The drl in the kjar is very simple:
package somerules
import org.json.JSONObject
import java.util.Map
rule "somerules - do something" ruleflow-group "somerules"
dialect "java"
when
$root : Map()
then
insert(new JSONObject());
delete($root);
end
And the bpmn should not be an issue (it is the same one used previously with our custom rulesengine):
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
targetNamespace="http://www.jboss.org/drools"
typeLanguage="http://www.java.com/javaTypes"
expressionLanguage="http://www.mvel.org/2.0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
xmlns:g="http://www.jboss.org/drools/flow/gpd"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools">
<process processType="Private" isExecutable="true" id="somerules" name="somerules" tns:packageName="somerules" >
<!-- nodes -->
<startEvent id="_1" isInterrupting="true"/>
<endEvent id="_jbpm-unique-0" name="End" >
<terminateEventDefinition />
</endEvent>
<businessRuleTask id="_jbpm-unique-2" name="somerules" g:ruleFlowGroup="somerules" >
<ioSpecification>
<inputSet>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
</businessRuleTask>
<!-- connections -->
<sequenceFlow id="_jbpm-unique-2-_jbpm-unique-0" sourceRef="_jbpm-unique-2" targetRef="_jbpm-unique-0" />
<sequenceFlow id="_1-_jbpm-unique-2" sourceRef="_1" targetRef="_jbpm-unique-2" />
</process>
<bpmndi:BPMNDiagram>
...
</bpmndi:BPMNDiagram>
</definitions>
I am building the kjar with drools 7.23.0.Final. I previously tried 7.22 as well.
Any advice appreciated, thanks.
I found out what the issue was, mainly by following advice given and trying to run the kie-server without Docker.
I got a lot of error messages (which were not visible to me in Docker) regarding dependencies and errors along the lines of "class X and class Y disagree on Z attribute".
This was because my kjar pom had dependencies already provided in the kie-server and there seemed to be conflicts. It was all the drools dependencies. By setting the scope to "provided" in the kjar pom for these dependencies, the issue was resolved and I could create the container (both in Docker and non-Docker kie-servers).

No suitable driver found for jdbc:mysql://localhost:3306/rom (Payara 5, Windows 10)

Believe me, I know this question has been asked many times and has gotten an answer many times, and these answers seemed to have worked for some users. I've spent many hours trying the various proposed solutions and, while they work on Linux (Ubuntu) they seem to have no effect on Windows (Windows 10 Home with jdk1.8.0_161). The web application is using EclipseLink 2.5.0 for persistence.
I've tried including the mysql-connector-java-5.1.46-bin.jar file in the WAR archive (WEB-INF/lib; using the Deployment Assembly screen in Eclipse), copying it to the payara5/glassfish/lib folder, as well as the payara5/glassfish/domains/domain1/lib/ and payara5/glassfish/domains/domain1/lib/applibs folders. I also tried specifying the library when deploying the web application, i.e., putting mysql-connector-java-5.1.46-bin.jar as the value in the library field. I updated the CLASSPATH environment variable with the path to the JAR file. Every time, the server was restarted. None of these actions have any effect. Note that they did work on Linux Ubuntu.
See below for the well-known exception trace:
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/rom
Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:326)
at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:138)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:170)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:228)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:804)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:254)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:757)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:216)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:324)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:348)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:311)
...
Any thoughts would be greatly appreciated.
UPDATE: as a sanity check (got the idea thanks to #Abhi) I added the line
try {
System.out.println("JDBC driver: " +
Class.forName("com.mysql.jdbc.Driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Which correctly prints the following line (without throwing an exception):
JDBC driver: class com.mysql.jdbc.Driver
But does nothing to solve the problem. In other words, the driver seems to be loadable but somehow EclipseLink is not able to find it (?)
Looks like I'm able to answer my own question. I asked the exact same question on the Payara Forum and was recommended to define a data source instead of using the driver directly (#Chris pointed in this direction as well). A data source is likely the best way to go anyway but I wanted to avoid the complexity and use the simplest setup .. which clearly didn't work.
For reference, you can find the working setup below:
In Payara 5, goto JDBC > JDBC Connection Pools > New: enter a pool name, select javax.sql.DataSource as resource type, and MySql as vendor. On step 2, com.mysql.jdbc.jdbc2.optional.MysqlDataSource should be preselected for Datasource Classname. Fill out the Username and Password (e.g., root, changeit) properties under the Additional Properties header. Select finish. On the page for the newly created connection pool, select PING to make sure it was setup correctly.
In your persistence.xml file, make sure the persistence-unit element starts as follows:
<persistence-unit name="ROM" transaction-type="JTA">
<jta-data-source>java:global/<connection pool name></jta-data-source>
Create a web.xml file (this may also be done using Java Annotations):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<data-source>
<name>java:global/<connection pool name></name>
<class-name>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</class-name>
<server-name>[host name, e.g., localhost]</server-name>
<port-number>3306</port-number>
<database-name>[db name]</database-name>
<user>[username, e.g., root]</user>
<password>[password]</password>
</data-source>
</web-app>
This configuration worked for me at least. Hoping this will help someone else down the road. Note that there are various useful settings for a connection pool - see e.g., here for more options.
to the line of code to connect:
con = DriverManager.getConnection(urlBaseDatos, usuario, clave);
Add the following:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
con = DriverManager.getConnection(urlBaseDatos, usuario, clave);
Naturally I concur with the answer here, which is "in an Application server you should use a DataSource".
Now just my two cents and to answer the original question:
From JDBC 4, you aren't required to register the driver anymore, and this line shouldn't be necessary:
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
See: https://docs.oracle.com/javase/8/docs/api/java/sql/DriverManager.html
So when using a JDK8+/EE8/JDBC4.2 compliant application server, you shouldn't be mandated to register the driver. Or so I thought...
Though, like you #William, I noticed Glassfish/Payara requires it. It's very strange. Maybe it has to do with the way it handles classloading?
Wildfly, in turn, does the right thing and automatically loads the driver without actually having to manually register it.

How to configure commit option for ejbs in Wildfly 10

I'm in the process of upgrading jboss from 4.2 to Wildfly 10.
As part of the EJB configuration, in the META-INF folder we have a jboss.xml with container configuration. The configuration is as below.
<?xml version="1.0"?>
<jboss>
<container-configurations>
<container-configuration extends="Standard BMP EntityBean">
<container-name>Standard BMP EntityBean with commit option C</container-name>
<commit-option>C</commit-option>
</container-configuration>
<container-configuration extends="Instance Per Transaction BMP EntityBean">
<container-name>Instance Per Transaction BMP EntityBean with commit option C</container-name>
<commit-option>C</commit-option>
<sync-on-commit-only>true</sync-on-commit-only>
</container-configuration>
</container-configurations>
<enterprise-beans>
<entity>
<ejb-name>TestEjbEntity</ejb-name>
<configuration-name>Instance Per Transaction BMP EntityBean with commit option C</configuration-name>
</entity>
<message-driven>
<ejb-name>ASyncActionExecutor</ejb-name>
<configuration-name>Standard Message Driven Bean</configuration-name>
<destination-jndi-name>queue/ASyncAction</destination-jndi-name>
</message-driven>
</enterprise-beans>
</jboss>
How do I do this in Wildfly 10?
There is no way to configure it as EJB2 EntityBeans are marked as optional for EE7.
Wildfly does not support the use of EnttyBeans, you should also see a WARN or ERROR message if you try to deploy such appliation.
I recommed to migrate to JPA.

Trying to configure an active MQ broker with a plugin in Java, where should <bean class="..."> attribute be pointing to?

I'm trying to configure an activemq broker with a plugin installed, but can't seem to get the qualified name of the plugin class right in the broker configuration file.
I have pasted the error message followed by the broker config below. Basicallly in the element I'm specifying
class="file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin"
which is absolute path to the XmlValidationPlugin.class file(have tried appending .class to path above but I get the same error).
Initially I assumed that the class attribute should be pointing to the .class file but have tried pointing it to .java and still doesn't work.
I have read the active MQ faq on developing plugins, FAQs, spring documentation etc.
My class path is
.;JAVA_HOME\lib;C:\Marcus\JavaProjects\Project;C:\Marcus\JavaProjects\Project\build\prod\classes
and JAVA_HOME is:
C:\Program Files\Java\jdk1.7.0_03
all the java source resides in
C:\Marcus\JavaProjects\Project\src
and the .class files are in
C:\Marcus\JavaProjects\Project\build\prod\classes
( file structure in classes mirrors that in src,so for example
com.foo.jms.amqplugin.XmlValidationPlugin
will have its .class file in
classes/com/foo/jms/amqplugin )
the plugin in question is XmlValidationPlugin.java, and is in folder src in package:
com.foo.jms.amqplugin
I have tried putting XmlValidationPlugin.class in a JAR and putting the JAR in activemqinstalldir/lib,( as was recommended to other people who had a similar problem) but this has not helped.
I have spent a day and a half on this already, and would really appreciate if anyone has any idea what the value of the plugins class attribute should be, as I have tried everything... Thanks in advance!
TOP OF ERROR OUTPUT:
C:\Program Files\apache-activemq-5.5.1>bin\activemq xbean:file:C:/Marcus/JavaProjects/Project/config/custom-broker.xml
Java Runtime: Oracle Corporation 1.7.0_03 C:\Program Files\Java\jdk1.7.0_03\jre
Heap sizes: current=15872k free=14246k max=506816k
JVM args: -Dcom.sun.management.jmxremote -Xmx512M -Dorg.apache.activemq.UseDedicatedTaskRunner=true -Djava.util.logging.config.file=logging.properties -Dactivemq.classpath=C:\Program Files\apache-
activemq-5.5.1\bin\../conf;C:\Program Files\apache-activemq-5.5.1\bin\../conf; -Dactivemq.home=C:\Program Files\apache-activemq-5.5.1\bin\.. -Dactivemq.base=C:\Program Files\apache-activemq-5.5.1\bin\
..
ACTIVEMQ_HOME: C:\Program Files\apache-activemq-5.5.1\bin\..
ACTIVEMQ_BASE: C:\Program Files\apache-activemq-5.5.1\bin\..
Loading message broker from: xbean:file:C:/Marcus/JavaProjects/Project/config/custom-broker.xml
INFO | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1#7a8ba4: startup date [Thu Apr 12 10:38:26 CEST 2012]; root of context hierarchy
ERROR: java.lang.RuntimeException: Failed to execute start task. Reason: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load type: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin. Reason: java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin; nested exception is java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin
java.lang.RuntimeException: Failed to execute start task. Reason: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load type: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin.
Reason: java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin; nested exception is java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin
at org.apache.activemq.console.command.StartCommand.runTask(StartCommand.java:98)
at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:57)
at org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:143)
at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:57)
at org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
...
BROKER CONFIG FILE:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- Allows us to use system properties as variables in this configuration file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.base}/conf/credentials.properties</value>
</property>
</bean>
<!--The <broker> element is used to configure the ActiveMQ broker. -->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost"
dataDirectory="${activemq.base}/data">
...
<!--plugin-->
<plugins>
<bean xmlns="http://www.springframework.org/schema/beans"
id="xmlValidationPlugin"
class="com.foo.jms.amqplugin.XmlValidationPlugin"/>
</plugins>
</broker>
</beans>
Basicallly in the element I'm specifying class="file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin" which is absolute path to the XmlValidationPlugin.class file(have tried appending .class to path above but I get the same error). Initially I assumed that the class attribute should be pointing to the .class file but have tried pointing it to .java and still doesn't work.
It seems that the error you are getting is from the classloader.
Reason: java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin; nested exception is java.lang.ClassNotFoundException: file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin
Classloader expects a fully qualified class-name instead of a path to the class file. Try to specify the fully qualified class name instead of the path to the class file .
Instead of:
file:C:/Marcus/JavaProjects/Project/build/prod/classes/com/foo/jms/amqplugin/XmlValidationPlugin
Use:
com.foo.jms.amqplugin.XmlValidationPlugin
and do make sure that CLASSPATH environment variable will contain: C:/Marcus/JavaProjects/Project/build/prod/classes
If ActiveMQ uses some custom classloader for loading plug-ins (I do not know the details), you might need to specify the classpath in some ActivemMQ-specific way.