How can I log to console / server.log from within a jboss module?
Say that I have a class:
public class MyClass {
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
private boolean done = false;
public void doSomething() {
logger.info("Look ma, I'm logging!");
done = true;
}
public boolean isDone() {
return done;
}
}
If I want to log from a deployed artifact (e.g., MyWebProject.war), all I have to do is:
Compile against slf4j-api
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
<scope>provided</scope>
</dependency>
Deploy
./jboss-cli.sh -c "deploy MyWebProject.war"
Profit
2015-10-19 11:04:02,445 INFO [com.myCompany.MyClass] (default task-13) Look ma, I'm logging!
But for the life of mine, I can't manage to do the same from within a jboss module.
Example: If MyWebProject.war uses MyModule.jar, and MyModule.jar is deployed as a jboss module:
${jbossHome}/modules/com/mycompany/mymodule/main
|____ MyModule.jar
|____ module.xml
Module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mycompany.mymodule">
<resources>
<resource-root path="MyModule.jar" />
</resources>
<dependencies>
<module name="org.slf4j" />
</dependencies>
</module>
If I move MyClass into MyModule.jar and use it from MyWebProject.war I can see the side effects (e.g., isDone() == true) but nothing is written to server.log.
What am I missing? Do I need any other module dependencies but slf4j?
For further reference, my problem had nothing to do with logging. The above recipe works as expected. In fact I've suffered because of a red herring: my original module.xml was never really used. I was actually loading a old class with the same name in another module. This old version of the class had no logging and should not be there to begin with.
Anyway, I think that the root cause of my problem (besides my lack of attention) was a small bug in jboss-cli.
I was deploying mymodule with the following command:
module add --name=com.mycompany.mymodule \
--resources=MyModule.jar \
--dependencies=org.slf4j \
--main-class=com.mycompany.mymodule.Main
This command was generating a module.xml like this:
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="com.mycompany.mymodule">
<main-class value="com.mycompany.mymodule.Main"/>
<resources>
<resource-root path="MyModule.jar"/>
</resources>
<dependencies>
<module name="org.slf4j"/>
</dependencies>
</module>
When I've finally managed to get my web project to try to load mymodule it failed with a stack trace such as:
18:45:59,999 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-7) MSC000001: Failed to start service jboss.module.service."deployment.MyWebProject.war".main: org.jboss.msc.service.StartException in service jboss.module.service."deployment.MyWebProject.war".main: WFLYSRV0179: Failed to load module: deployment.MyWebProject.war.war:main
at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:91)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.modules.ModuleLoadException: Error loading module from C:\opt\server\wildfly-9.0.1.Final\modules\com\mycompany\mymodule\main\module.xml
at org.jboss.modules.ModuleXmlParser.parseModuleXml(ModuleXmlParser.java:150)
at org.jboss.modules.ModuleXmlParser.parseModuleXml(ModuleXmlParser.java:127)
at org.jboss.modules.LocalModuleFinder$1.run(LocalModuleFinder.java:150)
at org.jboss.modules.LocalModuleFinder$1.run(LocalModuleFinder.java:144)
at java.security.AccessController.doPrivileged(Native Method)
at org.jboss.modules.LocalModuleFinder.findModule(LocalModuleFinder.java:144)
at org.jboss.modules.ModuleLoader.findModule(ModuleLoader.java:452)
at org.jboss.modules.ModuleLoader.loadModuleLocal(ModuleLoader.java:355)
at org.jboss.modules.ModuleLoader.preloadModule(ModuleLoader.java:302)
at org.jboss.modules.ModuleLoader.preloadExportedModule(ModuleLoader.java:313)
at org.jboss.modules.ModuleLoader.preloadModule(ModuleLoader.java:326)
at org.jboss.as.server.moduleservice.ServiceModuleLoader.preloadModule(ServiceModuleLoader.java:149)
at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:234)
at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:74)
... 5 more
Caused by: org.jboss.modules.xml.XmlPullParserException: Unexpected content of type 'element start' named 'main-class', text is: '<main-class value="com.mycompany.mymodule.Main"/>' (position: START_TAG seen ...n-class value="com.mycompany.mymodule.Main"/>... #5:54)
at org.jboss.modules.ModuleXmlParser.unexpectedContent(ModuleXmlParser.java:179)
at org.jboss.modules.ModuleXmlParser.parseMainClass(ModuleXmlParser.java:620)
at org.jboss.modules.ModuleXmlParser.parseModuleContents(ModuleXmlParser.java:445)
at org.jboss.modules.ModuleXmlParser.parseDocument(ModuleXmlParser.java:261)
at org.jboss.modules.ModuleXmlParser.parseModuleXml(ModuleXmlParser.java:148)
... 18 more
Taking a look at module-1_1.xsd I've found out that the main-class element was expecting a name attribute instead of a value attribute. So I've manually changed the module.xml to:
<main-class name="com.mycompany.mymodule.Main"/>
After I've restarted WildFly and redeployed my web project everything worked as expected.
Related
Currently I try, for my first time, to use Wildfly with MongoDB and Hibernate OGM. When I deploy my Project to Wildfly, the following error occurs:
"{ \"WFLYCTL0080: Failed services\" => {\"jboss.deployment.unit.\\\"{MYAPP}.war\\\".STRUCTURE\" => \"org.jboss.msc.service.StartException in service jboss.deployment.unit.\\\"{MYAPP}.war\\\".STRUCTURE: WFLYSRV0153: Failed to process phase STRUCTURE of deployment \\\"{MYAPP}.war\\\"
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYSRV0168: Error loading jboss-deployment-structure.xml from {MYUSERDIR}/wildfly10/standalone/deployments/{MYAPP}.war/WEB-INF/jboss-deployment-structure.xml
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[2,1]
Message: Unexpected element '{http://www.jboss.com/xml/ns/javaee}jboss-web'\"},
\"WFLYCTL0412: Required services that are not installed:\" => [\"jboss.deployment.unit.\\\"{MYAPP}.war\\\".STRUCTURE\"],
\"WFLYCTL0180: Services with missing/unavailable dependencies\" => undefined }"
My jboss-deployment-structure.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.hibernate" slot="ogm" services="import" />
<module name="org.hibernate.ogm.mongodb" slot="main" services="import" />
</dependencies>
</deployment>
</jboss-deployment-structure>
This Jboss Document mentions to add Modules (which I did) to the Wildfly Folder and add an Entry to the Manifest.mf File which I created manually.
Does anybody have an idea, what to try next?
I would also appreciate a Recommendation for a good Tutorial.
Sidenotes:
NetBeans 8.2
Wildfly 10
MacOS
MongoDB on Ubuntu 16.04 VM
I googled a lot
The Tutorial I basically used
My problem is that i have an ejb which internally uses freemarker tool to generate a HTML page, built and deployed to JBoss EAP 6.4.10. When i try to access this functionality (which generates HTML code using freemarker tool), jboss throwing below errors:
java.lang.LinkageError: Failed to link freemarker/core/TemplateElement
Caused by: java.lang.NoClassDefFoundError: javax/swing/tree/TreeNode
I added freemarker jar in my jboss modules and it's module.xml looks like this:
<module xmlns="urn:jboss:module:1.1" name="org.freemarker">
<resources>
<resource-root path="freemarker-2.3.25.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
Finally it is found out that the error is due to missing dependency 'javax.api' in freemaker's module.xml file, after adding this dependency in module.xml as below the problem has resolved.
<module xmlns="urn:jboss:module:1.1" name="org.freemarker">
<resources>
<resource-root path="freemarker-2.3.25.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
The Google App Engine has this same problem, that some classes that are mandatory in Java SE aren't present there. So try to use org.freemarker:freemarker-gae instead of plain org.freemarker:freemarker.
What kind of platform is that anyway, why's that class missing? Is it Google App Engine?
Update: Certainly JBoss EAP's class loader doesn't export the javax.swing package from some reason (see comments). While using freemarker-gae works that around, then you have to be careful to exclude the non-gae FreeMarker-s coming from elsewhere as transitive Maven (or Gradle, etc.) dependencies. So it would be more maintainable to fix the JBoss modules configuration instead. I saw some start JBoss EAP with -Djboss.modules.system.pkgs=javax.swing, though if Swing is available for other modules in the same JVM, then there must be a more elegant solution, such as adding something to deployment-structure.xml, or if you define your own JBoss modules then to its module.xml. Maybe you should check which standard module exports the swing packages ("javax.api"?), and try to declare that module as a dependency.
I am trying to upgrade my application from JBoss 7 to WildFly10, and I am getting a warning:
[0m[33m13:53:36,641 WARN [org.jboss.as.dependency.private] (MSC service thread 1-6)
WFLYSRV0018: Deployment "deployment.mywar.war" is using a private module
("org.jboss.as.jmx:main") which may be changed or removed in future versions
without notice.
The module is mentioned in jboss-deployment-structure.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure >
<deployment>
<dependencies>
<module name="org.jboss.as.jmx"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
how is called the new module for jmx? I tried to replace that with org.jboss.remoting-jmx but then I got
Invocation of init method failed;
nested exception is javax.management.JMRuntimeException:
Failed to load MBeanServerBuilder class org.jboss.as.jmx.PluggableMBeanServerBuilder:
java.lang.ClassNotFoundException: org.jboss.as.jmx.PluggableMBeanServerBuilder
according to WildFly forum it means nothing, see quote (source)
You got warning message as you are using internal "non-public" modules
from application server. Which just tells you that you should be
careful with this.
While deploying app.war (Struts 1.x) on my Wildfly this information appears:
Cannot upload deployment: {"WFLYCTL0080: Failed services" =>
{"jboss.deployment.unit.\"app.war\".POST_MODULE" =>
"org.jboss.msc.service.StartException in service
jboss.deployment.unit.\"app.war\".POST_MODULE: WFLYSRV0153: Failed to
process phase POST_MODULE of deployment \"app.war\" Caused by:
java.lang.RuntimeException: WFLYSRV0177: Error getting reflective
information for class org.ajaxtags.tags.AjaxDisplayTag with
ClassLoader ModuleClassLoader for Module \"deployment.app.war:main\"
from Service Module Loader Caused by: java.lang.NoClassDefFoundError:
au/id/jericho/lib/html/Segment Caused by:
java.lang.ClassNotFoundException: au.id.jericho.lib.html.Segment from
[Module \"deployment.app.war:main\" from Service Module Loader]"}}
I have downloaded jericho-html-2.6.1-sources.jar and placed this as a module into ${wf-dir}\modules\system\layers\base\au\id\jericho\lib\html\main\ with an module.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.3" name="au.id.jericho.lib.html">
<resources>
<resource-root path="jericho-html-2.6.1-sources.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
And there's still same issue...
Thanks for any help! :)
This was fixed by changing build system from Ant to Maven - looks like Wildfly has some problem while resolving directory conventions. On Glassfish 3.1.1 this worked with Ant
We have a working JBoss v8 "Wildfly" deployment like this:
App-ear.ear
|_App-model.jar
|_App-ejb.jar
|_App-web.war
This deployment comes with a persistence.xml inside the App-model.jar. Now I want to deploy a second EAR with a different WAR module that I can re-deploy independent from the original application. Therefor I've created a second EAR like this:
Second-ear.ear
|_Second-web.war
The second application has a classpath dependency to App-model.jar during development in Eclipse (setup as Maven projects) and builds just fine. To make that dependency available during runtime I've edited Second-ear.ear/META-INF/jboss-deployment-structure.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<dependencies>
<module name="deployment.App-ear.ear.App-model.jar" />
</dependencies>
</deployment>
</jboss-deployment-structure>
But the JBoss AS fails to load the persistence with the following error:
2015-08-19 09:13:36,903 ERROR [] [ # ] [] [MSC service thread 1-5] [fail] MSC000001: Failed to start service jboss.deployment.unit."Second-ear.ear".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."Second-ear.ear".WeldStartService: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
Caused by: java.lang.IllegalArgumentException: JBAS016069: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named MyPersistenceUnitName in deployment Second-ear.ear
at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:110)
at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceUnitInjectionPoint(WeldJpaInjectionServices.java:90)
at org.jboss.weld.injection.ResourceInjectionFactory$PersistenceUnitResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:279)
at org.jboss.weld.injection.ResourceInjectionFactory$PersistenceUnitResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:267)
at org.jboss.weld.injection.ResourceInjectionFactory$ResourceInjectionProcessor.createFieldResourceInjection(ResourceInjectionFactory.java:207)
at org.jboss.weld.injection.ResourceInjectionFactory$ResourceInjectionProcessor.createResourceInjections(ResourceInjectionFactory.java:182)
at org.jboss.weld.injection.ResourceInjectionFactory.discoverType(ResourceInjectionFactory.java:405)
at org.jboss.weld.injection.ResourceInjectionFactory.getResourceInjections(ResourceInjectionFactory.java:92)
at org.jboss.weld.injection.producer.ResourceInjector.<init>(ResourceInjector.java:59)
at org.jboss.weld.injection.producer.ResourceInjector.of(ResourceInjector.java:49)
at org.jboss.weld.injection.producer.BeanInjectionTarget.<init>(BeanInjectionTarget.java:62)
at org.jboss.weld.injection.producer.BeanInjectionTarget.createDefault(BeanInjectionTarget.java:46)
at org.jboss.weld.manager.InjectionTargetFactoryImpl.chooseInjectionTarget(InjectionTargetFactoryImpl.java:128)
at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:87)
at org.jboss.weld.bean.ManagedBean.<init>(ManagedBean.java:91)
at org.jboss.weld.bean.ManagedBean.of(ManagedBean.java:71)
at org.jboss.weld.bootstrap.AbstractBeanDeployer.createManagedBean(AbstractBeanDeployer.java:264)
at org.jboss.weld.bootstrap.BeanDeployer.createClassBean(BeanDeployer.java:228)
at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:78)
at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:75)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]
... 3 more
The CDI Bean that's trying to use that persistence unit injects an EntityManager produced by the original App-model.jar:
#Named("test")
public class Test {
#Inject
#MyModelDB // Qualifier
private EntityManager em = null;
// A simple test of the datamodel...
public Long numberOfProjects() {
if (this.em != null) {
return ((BigDecimal) this.em.createNativeQuery("select count(*) from e_bo_projects").getSingleResult()).longValue();
}
return -1L;
}
}
How can I solve this problem?
I've successfully deployed my two EARs now... thanks for your comments to my original question. My initial approach with 2 EAR including the same data-model JAR works, if the persistence.xml doesn't include the JNDI binding. Thanks #Franck! The mentioned jboss-deployment-structure.xml does no longer refer to my other EAR.
So now my deployment looks like this:
App-ear.ear
|_App-model.jar
|_App-ejb.jar
|_App-web.war
Second-ear.ear
|_App-model.jar
|_Second-web.war
This works for both applications and I've successfully accessed the database in both cases.