Related to Access restriction on class due to restriction on required library rt.jar? jaxb-impl has many classes that are provided by rt.jar, which is the reason behind the warning.
I generated my web service from a WSDL file.
If I'm meant to exclude jaxb-impl in order to get rid of the warning, what is it for then?
Which are the libraries I really need to keep for my web service to run, and which were only useful for generating the code related to it?
jaxb-impl is the JAXB implementation that CXF will use by default. In most cases, you can remove it at runtime (not at wsdl2java time though) and CXF will be ok. However, the jaxb-impl that CXF pulls in is generally newer than the versions found in the JDK and usually has several bugs fixed that would still be present in the in-JDK versions of JAXB. CXF and CXF users tend to stress JAXB pretty hard and find interesting issues that we log with them and eventually get fixed.
Related
How do I attach logback to smartfox server?
smartfox uses log4j by default. How can I shift logging of my extensions/all of smartfox to logback?
I've tried this but this is failing with this error cause it has already boud to log4j I guess.
SmartFoxServer 2x uses Simple Logging Facade for Java (SLF4J) for logging. The very purpose of SLF4J is to provide a facade over the logging framework so the user can replace one logging framework with another. In your case log4J with Logback. I'll first explain how SLF4J works and how you can change one logging framework with another and briefly discuss some caveats. Then I'll cover some SmartFoxServer specifics.
Simple Logging Facade for Java Architecture
SLF4J provides API which serves as facade (abstraction layer) over the actual logging framework. This allows the user to easily switch between frameworks on deployment time without the need to change the code. But it also means that SLF4J on its own is not enough - the default implementation is no-op. In order to actually log anything you need actual logging framework (such as log4j or logback) and so called "binder" which servers as a bridge or adapter between SLF4J and the logging framework.
Swapping Logging Frameworks
The SLF4J User Manual provides detailed explanation on how you can swap one framework with another during deployment time. In short you just need to delete the old binder and logging framework and add the new binder and the new logging framework. To swap log4 with logback you need to delete slf4j-log4j12 and log4j jars and add logback-classic and logback-core.
Caveats
You should make sure that there is only one binder implementation in the classpath. Having more than one causes waring, not error. SLF4J would just pick one of the implementations. But I would not rule out the possibility for this to cause issues with more complex application (such as SmartFoxServer) that uses multiple class loaders. But more importantly you should make sure the SLF4J API, the binder and the logging framework versions are compatible. For example if you use old version of SLF4J with newer version of logback that may cause ClassNotFoundException. I suspect that this could be reason why you get the error you see.
Swapping lof4j with Logback as logging framework for SmartFoxServer 2x
SmartFoxServer 2x version 2.17.3 uses SLF4J API version 1.7.5. To swap log4j you need to first delete lib/slf4j-log4j12-1.7.5.jar and then add compatible version of logback-classic and logback-core jars. For example logback-classic 1.1.0 and logback-core 1.1.0.
You can delete lib/log4j-1.2.15.jar but I would rather keep it. The binder(lib/slf4j-log4j12-1.7.5.jar) is not meant to be used directly so it should be safe to be deleted. On other hand there are libraries that use log4j directly. I don't know if SmartFoxServer 2x uses any such library but it is safer to keep it just in case. Swapping the binder is enough for SLF4J to use Logback and ignore log4j.
Logger Output
SmartFoxServer 2x parses the logger output to provide some functionality such as the Admin Log Viewer. If you change the log output this may cause this functionality to stop working and maybe even cause other issues (on theory it should not, but you never know). There is configuration file (config/logParser.properties) that would allow you to configure the log parser, but I didn't found any documentation about it. You may try to ask on the SmartFoxServer forum. The developers are actually pretty active there so they may help.
Swapping loggers only for your extension
The instruction I gave swaps the logger for all extensions and SmartFoxServer. If you want you may try to swap them only for your extensions. But I'm not quite sure if and how that would work. Each class extension uses its own class loader but this provides isolation between extensions and SmartFoxServer and extensions, but not between extension and SmartFoxServer. What does this mean is that if you add lib.jar to Extension A classpath it would not be visible to Extension B or to SmartFoxServer code. But if you add lib.jar to the SmartFoxServer classpath it would be visible to both Extension A and Extension B. As SmartFoxServer already contains SLF4J API on its classpath you should not add it to your extension classpath. You can try to add logback-classic and logback-core to you extension classpath. But in this case you'll have two binder implementations in you extension classpath (logback and log4j from the SmartFoxServer classpath). As already discussed, I'm not quite sure how and if this would work.
Conclusion
SLF4J provides an easy way to swap logging frameworks, but there some caveats. And SmartFoxServer adds some caveats on its own. Unless SmartFoxServer team supports swapping of the underlaying logging framework (which judging by some anwers in their forum, they don't), I would be quite careful and do such swap only if there are some benefits and it is not just a matter of personal preference.
I’m trying to use JAXB 2.2.11 in an osgi environment (Liferay DXP). I am having issues creating a JAXBContext. Based on some other sources found while researching like this and this, I have determined that in an osgi container I need to provide the correct classloader for JAXB to instantiate the context. So I have code like this:
ClassLoader cl package.with.jaxb.objects.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("package.with.jaxb.objects ", cl);
This code causes a null pointer exception with the following stack trace:
Caused by: java.lang.NullPointerException
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:129)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:201)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:146)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:371)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:446)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:409)
Looking at the source for ContextFinder I can see that context must be null on line 129:
throw handleClassCastException(context.getClass(), JAXBContext.class);
I thought perhaps the problem was that my module has a dependency on jaxb-api 2.2.11 but the jaxb-impl classes are provided by rt.jar at runtime and are probably newer than 2.2.11 because Liferay DXP runs on JDK 1.8. To get around this issue, I have tried including jaxb-impl.jar 2.2.11 as a dependency in my osgi module, thinking then the jaxb-api & jaxb-impl versions would match. After that, trying to create a JAXBContent using the same code as above results in the following error:
ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_144/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://623.fwk616113009:13/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader.
By the looks of this message, the JAXBContext that is getting instantiated is from the version of JAXBContext that is loaded via rt.jar. This is very confusing to me because I would expect the version of JAXBContext loaded by my module’s classloader to be used since I’ve included jaxb-impl.jar in my module and I’ve specified my module’s classloader is the one to be used in my call to JAXBContext.newInstance. Can anyone shed some light on how I can get jaxb 2.2.11 to work in an osgi container?
*Please note that I can’t upgrade the version of jaxb-api used by my module because the JAXB code is actually in a 3rd party jar that requires jaxb 2.2.11 (I have just eliminated the 3rd party jar from the equation for now by writing some test JAXB code).
After extensive research I found the following solution. Since it seemed like passing the bundle class loader as suggested by the accepted answer in this post had to be correct, I followed the path of figuring out why I was getting a NullPointerException when I tried that. After carefully looking over the source code for jaxb-api to follow the stack trace of the NullPointerException, I could see that the jaxb-api code does things like
classLoader.loadClass("com.sun.xml.internal.bind.v2.ContextFactory")
where classLoader is my bundle's class loader (since that's what I passed in) and ContextFactory is actually a class in jaxb-impl which is loaded by the bootstrap class loader. This is where the problem lies because my
bundle's classloader isn't going to be able to see classes loaded by the bootstrap class loader. This threw me for a while because I'm not used to how class loaders work in osgi. I incorrectly was thinking the classes loaded by the bootstrap class loader would be visible because I'm used to web app class loading where there is delegation. In osgi class loaders
are completely isolated from each other, things are only visible if they are exported. To get around the issue I found some helpful posts talking about similiar issues. It turns out there is a concept
called boot delegation in osgi where you can specify a list of classes/packages to always be loaded via the bootstrap classloader. So the end result is two steps:
1) Switch the thread's class loader to your bundle class loader before calling the code to get the JAXBContext:
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
// ObjectFactory here is in the same package as my classes to be marshalled
ClassLoader objectFactoryClassLoader = ObjectFactory.class.getClassLoader();
Thread.currentThread().setContextClassLoader(objectFactoryClassLoader);
// JAXB code goes here
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
2) Specify packages to be loaded using the boot delegation mechanism. This list needs to include the transitive dependencies of the classes you need loaded. In my case, I'm using Liferay so the list
is specific to Liferay and it goes in portal-ext.properties configuration file. Luckily I found this post where someone had done most of the work for me:
module.framework.properties.org.osgi.framework.bootdelegation=\
__redirected,\
com.liferay.aspectj,\
com.liferay.aspectj.*,\
com.liferay.portal.servlet.delegate,\
com.liferay.portal.servlet.delegate*,\
com.sun.ccpp,\
com.sun.ccpp.*,\
com.sun.crypto.*,\
com.sun.image.*,\
com.sun.jmx.*,\
com.sun.jna,\
com.sun.jndi.*,\
com.sun.mail.*,\
com.sun.management.*,\
com.sun.media.*,\
com.sun.msv.*,\
com.sun.org.*,\
com.sun.syndication,\
com.sun.tools.*,\
com.sun.xml.*,\
com.yourkit.*,\
org.eclipse.persistence.internal.jaxb,\
org.eclipse.persistence.internal.jaxb.*,\
javax.xml.*,\
sun.*
Helpful links:
Why can't JAXB find my jaxb.index when running inside Apache Felix?
What is the difference between bootdelegation and DynamicImport-Package in osgi
https://web.liferay.com/web/user.26526/blog/-/blogs/liferay-dxp-and-weblogic-
https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/bundle-classloading-flow
http://apache-felix.18485.x6.nabble.com/Classloading-for-JAXB-td4834670.html
Here is the workaround that worked for me using JDK 11, Liferay DXP/7.2, OSGI, with a sample Jax-RS web service created from Dev Studio. The error I was getting was as follows when trying to access the web service:
JAXBException occurred : Implementation of JAXB-API has not been found
on module path or classpath..
com.sun.xml.internal.bind.v2.ContextFactory cannot be found by
org.apache.aries.jax.rs.whiteboard_1.0.4.
What worked for me was to define the context factory at the system level to override the predefined context factory. Add the following system variable to your system
javax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory
For example you can add this in your setenv.sh/bat file in Tomcat, or in eclipse you can access your server Launch Configuration, Arguments tab, under VM arguments
-Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory
This worked without adding any extra libraries since Liferay already has those libraries included.
How does this work? Refer to the javadoc for JaxBContext and read the Discovery of JAXB implementation Section. Using the /META-INF/services/javax.xml.bind.JAXBContext file did not work for me.
I hope this helps someone.
One final note for DXP users, if you get a permission denied on your service then you need to read about Service Access Policies
The best place to see how it should be done is Apache Karaf. It doesn't install any JAXB-API bundle - instead it uses org.apache.servicemix.specs.jaxb-api-2.2-2.7.0.jar inside lib/endorsed directory.
This way you won't use JAXB-API provided by rt.jar.
For implementation - it's best to use ServiceMix version of JAXB bundles:
org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-impl:2.2.11_1
org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-xjc:2.2.11_1
I know that there are already some questions related to this topic but I couldn't find a real solution yet.
Currently I am developing applications with EE6, using JPA, CDI, JSF. I would like to take a more modular approach than packaging everything into a WAR or EAR and deploy the whole thing on an Application Server.
I am trying to design my applications as modular as possible by separating a module into 3 maven projects:
API - Contains the interfaces for (stateless) services
Model - Contains the JPA Entities for the specific module
Impl - Contains the implementation of the API, mostly CDI beans
The view logic of every module is currently bundeled within a big web project, which is ugly. I already thought of web fragmets, but if I spread my bean classes and xhtml files in jar files, I would have to implement a hook so that the resources could be looked up by a parent web application. This kind of solution would at least enable me to have a fourth project per module that would contain all the view logic related to the module, which is a good start.
What I want is not only that I can have those 4 kinds of projects, but also that every project is hot swappable. This led me to OSGi, which was at first really cool until I realized that the EE6 technologies are not very well supported within an OSGi Container.
JPA
Let's look at JPA first. There are some tutorials[1] around that explain how to make a JPA enabled OSGi Bundle, but none of these tutorials shows how to spread entities into different bundles(the model project of a module). I would want to have for example three different modules
Core
User
Blog
The model project of the blog module has a (compile-time)dependency on the model project of user.
The model project of the user module has a (compile-time)dependency on the model project of core.
How can I make JPA work in such a scenario without having to create a Persistence Unit for each model project of a module? I want one persistence unit that is aware of all entities available at runtime. The model projects in which the entities are should of course be hot swappable. Maybe I will need to make a separate project for every client that imports all the needed entities of the projects and contains a persistence.xml that includes all necessary configuration things. Are there any available maven plugins for building such a projects or even other approaches to solve that issue?
CDI
CDI is very nice. I really love it and I don't want to miss it any more! I use CDI extensions like MyFaces CODI and DeltaSpike which are awesome!
I inject my (stateless) services into other services or into the view layer which is just great. Since my services are stateless it should not be a problem to use them as OSGi Services, but what about CDI integration in OSGi? I found a glassfish CDI Extension[2] that would the injection of OSGi Services into CDI beans, but I also want may OSGi Services to be CDI beans. I am not totally sure how to achive that, probably I would have to use the BeanManager to instantiate the implementations and then register every implementation for its interface in the ServiceRegistry within a BundleActivator. Is there any standard way for doing that? I would like to avoid any (compile-time)dependencies to the OSGi framework.
I would also like to use my services just like I use them right now, without changing anything(implementations not annotated and injection points not qualified).
There is a JBoss Weld extension/sub project[3] that seems to target that issue but it seems to be inactive, i can't find any best practices or how-tos.
How can I leave my implementation as it is but still be able to use OSGi? I mean it would not be a big deal to add an annotation to the implementations since every implementation is already annotated with a stereotype annotation, anyway I would like to prevent that.
JSF
As mentioned before I would like to be able to spread my view logic module wise. As far as I know this is not really possible out of the box. Pax Web[4] should solve that somehow, but I am not familiar with it.
I would like to have a project "CoreWeb" in the module "core" that contains a Facelet template, let's call it "template.xhtml". A JSF page in a project called "BlogWeb" in the module "blog" should then be able to reference that template and apply a composition.
To be able to extend the view I would introduce a java interface "Extension" that can be implemented by a specific class of a module. A controller for a view would then inject all implementations of the extension. An extension would for example provide a list of subviews that will be included into a main view.
The described extension mechanism can be implemented easily, but the following requirements must be fulfilled:
When adding new OSGi Bundles to the application server, the set of available extensions might change, the extensions must be available for the controller of the view.
The subviews(from a separate bundle) which should be included into a main view should be accessible.
The concept of a single host but multiple slice applications of Spring Slices[5] is very interesting, but seems limited to Spring DM Server and the project also seems to be inactive.
Summary
After all the examples and behaviors I described I hope that you know what I would like to achive. It's simply an EE6 App that is very dynamic and modularized.
What I look for at the end is at least documentation on how to get everything running as I would expect it or even better an already working solution!
[1] http://jaxenter.com/tutorial-using-jpa-in-an-osgi-environment-36661.html
[2] https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi
[3] http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi
[4] http://team.ops4j.org/wiki//display/paxweb/Pax+Web
[5] https://jira.springsource.org/browse/SLICE
To answer some of your questions, using a single persistence unit but spreading your entities across multiple bundles is not recommended, but may occasionally work. However, if your entities are so closely related that they need to share a persistence unit, splitting them across modules may not make sense. Also, don't forget you can handle compile-time dependencies by separating the implementation and interface for each entity - interface and implementation need not be in the same bundle.
For dependency injection, you may like Blueprint.
Several implementations are available and most application servers with enterprise OSGi support support Blueprint out of the box. It uses XML to add metadata, so classes themselves won't need any modification.
Probably is a straight-forward question: do you know any tools for combining multiple wsdl + xsd files into a single wsdl?
Thank you.
Edit1:
The service is a WCF service, and I want to have a single wsdl for PHP (as client).
Edit2:
Too bad I need to use .Net 4.0 and not 4.5 where this would be possible. Maybe I could borrow then one of the new MS tools? Do you know which one? Is the svcutil.exe the responsible tool? If yes, what are his dependencies? Because I don't want to jump to .Net 4.5 just yet.
You can build a small application that can generate a flat wsdl. We do generate flat wsdl programatically in C# for building interoperable WCF services. Refer to the link on how to generate flat wsdl.
Hopefully seeing the code you can build a tool that does it for you.
Else you can manually do it using Altova Xml Spy and replacing the xsd import attributes by the xsd schema definition.
For sure, I can recommend a tool that can combine multiple XSD files into the minimum set possible (I am biased here, since I wrote it). This in itself can be a heavy task, if you have a large number of files, many namespaces, or both. The things might get trickier for multiple WSDLs into one, depending on some parameters you may have configure; for example, is it logically one WSDL authored over three layers that maintains separation of messages - portTypes - services, or multiple WSDLs, period? One thing you must ensure is that all share the same types subsystem, there's no conflict for operations, etc. But even this is a task that could be achieved, I could easily put an addon out... If this is refactoring of XML Schemas and WSDLs you see doing often, let me know.
We wanted one wsdl file to make use of some tools to automatically generate soap proxy on PHP side. But we ended up writing the DTO layer manually.
If you have wcf service in .NET 4.5 you can get easily only one wsdl file (inbuilt feature of WCF framework).
I am running into an issue with JAXB 2 when marshaling my objects. I have an XmlJavaTypeAdapter which is working perfectly fine in unit tests, but when I try to marshal the same object graph from a web service (using JAX-WS), the XmlJavaTypeAdapter is being ignored completely. What's the easiest way to debug this problem?
I have a simple standalone project checked into my svn repository that demonstrates this issue. Can somebody please take a look to see if I am doing something obviously wrong? The URL for the project is: http://archfirst.googlecode.com/svn/trunk/java/examples/jaxb-jaxws-sample. There is a readme.txt file in the root folder that describes the issue in detail.
Thanks.
Ok, I finally found the problem. My unit test was picking up the JAXB implementation in the Java runtime, whereas my web service was picking up the JAXB implementation from GlassFish. Apparently the implementation bundled with GlassFish (2.2.1.1) cannot handle my use case. I proved it by forcing my unit test to use jaxb-impl-2.2.1.1.jar. Also it seems that the bug has been fixed in the latest JAXB implementation (2.2.3-1), but I am struggling to figure out how to replace GlassFish's implementation with this new version (see my post here).