Websphere Liberty Profile Can't find bundle for base error - eclipse

I have an EAR installed in eclipse on WLP 8.5.5.3
This is the EAR entry with a classloader attached:
<enterpriseApplication id="App4EAR" location="App4EAR-4.1.5-SNAPSHOT.ear" name="App4EAR">
<classloader apiTypeVisibility="spec,ibm-api,api" delegation="parentFirst" commonLibraryRef="baseLibraries.app4">
</classloader>
</enterpriseApplication>
The server is starting without issues. The first jsp page in the application tries to read a properties file which is located in the WAR component. This is where it fails.
SRVE0777E: Exception thrown by application class 'java.util.ResourceBundle.throwMissingResourceException:1427'
java.util.MissingResourceException: Can't find bundle for base name prop.appadmin, locale nl_BE
The object that reads the properties is located in the web application together with the properties file. The utility class for reading the resource bundle is in a separate jar and is part of a shared library (baseLibraries.app4).
This is an entry from the App4EAR.ear.xml deployment definition that points to folder where the properties file is located:
<dir sourceOnDisk="C:\svn\app4\App4Web\target\classes" targetInArchive="/WEB-INF/classes"/>
When using java.util.ResourceBundle() directly in the application it successfully locates the properties file. But not so when we use the utility class from the shared library.
Why is a shared library not able to access properties resources in the main web application?

Your shared library is loaded in parent classloader, and the classes and also properties in your application are not visible to that classloader thats why they cannot be found. Add property files to the classpath of the library instead of web app.

Packaging the utility jar, that accesses the resource file, in the web application solves the problem.
This solution kind of negates the purpose of shared libraries. Also note that on WAS 8.5 this was not a problem, so something did change in the way shared libraries are exposed/loaded.

Related

Where do I place my templates for Blog-related mail notifications in Liferay 7.0?

The documentation states that I can configure the liferay server to use my own templates for the email messages. Specifically, if I add these properties to a portal-ext-env.properties in $CATALINA_BASE/conf/liferay:
blogs.email.entry.added.enabled=true
blogs.email.entry.added.subject=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_subject.tmpl}
blogs.email.entry.added.body=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl}
Liferay will supposedly use the templates in the specified paths (com/liferay/portlet/blogs/dependencies/email_entry_added_subject.tmpl and com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl). The thing is, it's not very clear what these paths are relative to. Are these files relative to $CATALINA_BASE? For example, would the above configuration result in Liferay looking up $CATALINA_BASE/com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl for creating the body of an email message? If this is not the case, where does Liferay lookup templates for Blog-related email messages?
After some digging, I've found that you place the templates in the $CATALINA_BASE/webapps/ROOT/WEB-INF/classes folder. Paths that you reference in the properties (e.g. blogs.email.entry.added.body=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl}) are relative to the aforementioned classes folder.
So, if I wanted Liferay to use a template file in the ff. relative path: org/foo/my_email_entry_added_body.tmpl, I would do two things:
Place the file in $CATALINA_BASE/webapps/ROOT/WEB-INF/classes/org/foo/my_email_entry_added_body.tmpl.
Add the following line to $CATALINA_BASE/portal-ext-env.properties: blogs.email.entry.added.body=${resource:org/foo/my_email_entry_added_body.tmpl}.
I consulted my co-worker and got a better understanding of why this is. The architecture of a Liferay application is such that it comes bundled with a Tomcat server. According to the documentation, WEB-INF/classes is a directory that a web app deployed to a Tomcat server looks up for classes and resources:
A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.
Specifically, this folder is high in priorty in the web app's classpath.
When you see Liferay code similar to ${resource:path/to/foo}, it's looking up resources in its classpath. One of the paths in that classpath is WEB-INF/classes. Hence, if path/to/foo is placed in WEB-INF/classes, Liferay will find path/to/foo there.

GWT hosted mode and tomcat deploy differences

I have a very specific problem dealing with GWT. I have a web application and a jar file which contains the business logic. Inside this jar I use dozer mapper and I have the related config file inside the jar itself. The config file is under META-INF/dozer_mappings.xml. While in hosted mode it works perfectly, in web mode it has a problem. It says:
Unable to locate dozer mapping file [/META-INF/dozer_mappings.xml] in the classpath!
Actually I don't understand why it should change: if the file is not in the classpath it should not work in both the environments... Of course all my libraries are in the WEB-INF/lib folder. The one with the dozer configuration is there as well.

How to teach JAXB to locate classes in another project's .jar?

I am having trouble teaching JAXB to locate classes in a .jar file located in an other Eclipse project.
We are developing several web applications. Each application is a separate Eclipse project which eventually is packaged as a separate OSGi plugin which is then deployed to our server runtime.
The services that each application provides is specified using WSDLs. Since all services are using several common data structures, we moved those definition into a separate schema which is located in a "Shared" project and all WSDLs import that schema using an import statement like:
...
<xsd:schema>
<xsd:import namespace="SharedTypes.v1_1.xsd"
schemaLocation="../Shared/SharedTypes.v1.1.xsd">
</xsd:import>
</xsd:schema>
...
i.e. they reach out of their own project ('..') and peak into the "Shared" project to import that schema.
The XML<=> Java bindings generated from that shared schema are saved to a .jar called "xsd.v1.1.sharedtypes.jar" which is placed in the /libs-folder of project "Shared".
That jar contains all classes corresponding to the types defined in the schema. An element, say, 'X' is compiled into a corresponding class "xsd.v1.1.sharedtypes.X". This .jar is declared as being exported from the "Shared" OSGi bundle.
The referencing OSGi bundles import this bundle, i.e. they declare "Shared" as a dependency.
The problem arises, when we try to generate the XML<=> Java bindings from the WSDL's in each project. There we always get a compile error in which the Eclipse JAXB wizard declares that it can't compile the classes it just generated from the WSDLs because it cannot find the classes that are contained in that shared .jar file.
But that .jar DOES contain the missing classes. It is also declared as being exported by the "Shared" plugin. And that plugin is being imported into the Applications' plugins. So these class should be visible at compile time, but obviously the JAXB-compiler sees that differently!
Any idea, how one can teach JAXB to include the exported .jar's of referenced OSGi plugins into the compilation's classpath when creating the XML-binding code?
Hope I could make myself clear...
M.

Manifest.MF vs libraries.xml vs deployment.xml

So I am having issues deploying code to my local websphere server (imagine the dred I have for installing it to my test server).
I get a java.lang.ClassNotFoundException when I attempt to run the application.
So after googling around it seems as though I need to add entries into one of the above files. Problem is, there doesn't seem to be good examples of how to do that.
In the Manifest.mf file, do I need to add the fullpath to where I expect the jar to be? Does anybody have a good example of a deployment.xml/libraries.xml? How do I translate what is in my project classpath to entries into those various files?
Start with 'Websphere Class Loaders'.
Usually the order to load/find a class/resource is :
Current Module(war/jar/sar) --> (if not found then look inside) -->
Another Module in EAR (via manifest.mf) --> (if not found then try to load it from) -->
Common shared library (libraries.xml) (or) Extensions library -->
(if not found, then throw the error Class not found/No class Def found error).
Manifest.mf
Using this file you could point to the module/location directly to load the required classes/resources.
libraries.xml
Here you can define and maintain the shared libraries which can be used across many JVM's (like single jar file can be referenced from multiple jvm instances). Refer this for more information.
In my experience, I try to avoid using manifest.mf files, and refer the library jar files from shared library 'libraries.xml' file. (or) if you are trying to learn the Web sphare, then just include the jar files in lib/ folder of your package.

How can you develop bottom-up JAX-WS web services referencing classes contained in separate jar files?

I am developing a Java EE 6 bottom-up JAX-WS to expose an EJB3.1 stateless session bean. The web service in a WAR is failing to install on deployment because it references an external jar (or shared library) which one can assume is not loaded yet.
The common suggestion is to include the jars in the /lib folder, which does fix the issue, however the jars need to remain in this external shared library location and NOT in the ear file, because they amount to 30MB.
What are some techniques to get around this issue in a Websphere (WAS v.8) environment or any server environment.
Some suggestions I have found include:
1. define classpath in META-INF file.
2. define the resources in deployment.xml
3. alter class loading order
4. (from ibm) In the case where the jars are part of a Shared Library configured on WebSphere Application Server, then a User Library must be used to configure the project for development before generating the WebService.
However, I have been unsuccessful to find any help online in these areas. Is there another technique or does anyone know anything about accomplishing this? Thanks in advance.
EDIT: If I specify the libraries in the META-INF using class-path, they are loaded before extensions, shared libraries..etc, but they are still loaded after the WAR which is not good. Again, this isn't a runtime issue because the web services are created at deployment on the fly.
I submitted a ticket to IBM. The libraries referenced by the web service are needed during deployment and must be bundled into the Ear in some fashion. I threw them in the web-inf/lib folder. However, if the referenced libraries then depend on additional libraries, these can be placed in the Shared Libraries. Seems odd to me too, but let's all just admit "shared libraries" are a hack anyways.
If you still have issues, just make sure your class loading is set to parent_last.