Details
-
Type:
Improvement
-
Status:
Closed
-
Priority:
Minor
-
Resolution: Fixed
-
Affects Version/s: 2.7
-
Fix Version/s: 2.8
-
Labels:None
-
Environment:Oracle WebLogic
-
Testcase included:yes
-
Patch Submitted:Yes
-
Number of attachments :5
Description
The current handling of defaultLibBundleDir leads to some issues on Oracle Weblogic 10+. The Ear plugin currently sets library-directory to the value of defaultLibBundleDir in the application.xml for EARs v5+. Some of Oracle's classloading features break (specifically "Generic File Loading") when this element is set. defaultLibBundleDir has to be set to APP-INF/lib since this is the magic library folder for WebLogic.
The patch adds a parameter to prevent setting library-directory for cases like this.
-
- ear-remove-librarydirectory-IT.patch
- 24/Jan/12 3:31 PM
- 5 kB
- Alex Halovanic
-
- ear-remove-librarydirectory-IT.patch
- 09/Aug/12 12:47 PM
- 5 kB
- Alex Halovanic
-
- ear-remove-librarydirectory.patch
- 24/Jan/12 3:31 PM
- 4 kB
- Alex Halovanic
-
- ear-remove-librarydirectory.patch
- 09/Aug/12 12:47 PM
- 6 kB
- Alex Halovanic
-
- ear-general-librarydirectory.patch
- 26/Aug/12 9:25 PM
- 3 kB
- Alex Halovanic
Activity
You've got it exactly. Definitely a bug in WebLogic. I am working on putting together a bug report with Oracle, but from past experience, if they don't first tell me this is intended behavior, they won't release a fix to others since it's not a security flaw.
In that case, I prefer a weblogic configuration option, like we've done for JBoss. Your patch is a too wide option that sole purpose is to workaround a bug.
Something like
<configuration> <weblogic> <write-library-directory>false</write-library-directory> </weblogic> </configuration>
Well, fair enough, I'm not too happy about an option just for working around a bug.
But you did bring up the point that library-directory would only get written if defaultLibDirectory is set. Can I ask, is there a reason why JARs are written to the root by default? From http://java.sun.com/xml/ns/javaee/application_5.xsd:
"If this element [library-directory] isn't specified, the directory named "lib" is searched."
Should jars be written to lib/ by default instead of the root? It seems to be the expected location according to the spec and would seem to eliminate the need for defining defaultLibDirectory in most cases.
Well, I think you got it wrong or I am missing something. Your request IS about working around a bug!
The answer is backward compatibility. This option was present way before JavaEE5 came out (actually it was mostly used on old weblogic version and the magic APP-INF/lib thing). Changing the behavior of an existing option according the version of the spec you use is a bit tricky.
The other reason is that users (for mysterious reasons) keep on willing to put libs in the root. If you change the default, it's harder to justify the behavior breakage.
I was agreeing with you about it being a workaround for a bug; I'm fine with rewriting the patch to make it be listed as for WebLogic only. I think I should just wait for Oracle to get back to me about this before I do, in case they have a more appropriate fix.
I have the response back from Oracle:
You can either use AppFileOverrides directory (and let the container do the classloading discovery), or you can use <library-directory> and you decide where you want the files to come from. You should not use both.
By default, library-directory will be loaded from APP-INF/lib of the EAR anyways, rendering the explicit <library-directory> inside the application.xml is redundant.
When no <library-directory>, you're delegating the classloading to the container (ie. WLS), and the documented behavior below will suffix :
http://docs.oracle.com/cd/E12839_01/web.1111/e13702/config.htm#i1066493
However, if you explicitly define <library-directory> in application.xml, this would take precedence, and since you specify the following -
...
<library-directory>APP-INF/lib</library-directory>
...
.
in which you have the following file in APP-INF/lib in classloader-ear-libdir.ear -
.
classloader-jse-1.0-SNAPSHOT.ear
.
In such case, you're essentially overriding the AppFileOverrides directory.So you can either use <library-directory> or AppFileOverrides, but not both. If both are specified, <library-directory> will take precedence.
So in their opinion, this is not a bug, but intended behavior and always defining <library-directory> to the default EAR lib folder has side-effects. However, unless there's another product that has special classloading overrides like this, it's almost certainly still WebLogic-specific.
Stéphane, in light of Oracle confirming this being intentional behavior for the foreseeable future, do you still think it makes sense to modify this to have a specific WebLogic section for this option?
I feel like introducing a PlexusConfiguration just to nest a parameter is going to make invoking this option unnecessarily complex. For example, the ear:ear goal documentation is not going to list this flag if it's nested under a Configuration class. Also, unlike the JBoss options, this does not modify a separate file, but has consequences for application.xml.
FYI, the library-directory entry in application.xml causes WebLogic 12.1.1 to throw a "weblogic.deployment.EnvironmentException: duplicate persistence units with name" when using local development mode and copying EAR to autodeploy directory. (Not certain of outcome when deploying through AdminServer using WebLogic's deployer tool.) This problem isn't present under WebLogic 10.3.x even with the same EAR structure, i.e. packaging libs under APP-INF/lib per spec. Removing the library-directory entry manually from the application.xml makes the app work normally under WebLogic 12. I've been watching this issue, hoping to get an alternative workaround in case WebLogic decided this was a "feature" in their app server.
The specific problem with the library-directory entry is that, under WebLogic 12, the server attempts to load persistence.xml out of the autodeploy folder as well as under the <server>/tmp/_WL_user (working area for the deployment). It's actually the same persistence.xml file, just placed in the tmp work space by WebLogic.
PS: Our application doesn't care about custom classloading. I understand our issues are unrelated, but this fix would solve my problem.
So yes we can do that. A patch would obviously help integrating this feature (the one attached provides a general parameter, I don't think we should go that way. Starting weblogic specific options is probably the best option).
That would work and be clear. BTW, I mentioned this side-effect to an Architect at Oracle during a sales meeting. She said that she would pass along the issue to the team. I have not heard back from anyone or have seen a new version of WebLogic, yet. Thanks for providing a workaround!
The jars need to be placed under APP-INF/lib of the EAR for newer versions of WebLogic to pick up libraries shared between WAR and EJB JAR, within the same application. The defaultLibBundleDir configuration option in Maven EAR plugin allows for putting all common libs under this specified directory. It also has the side effect of adding the library-directory element to the application.xml.
An empty library-directory element would mean an empty defaultLibBundleDir argument, which would not package the common JARs where they need to be for WebLogic. Or do you have something else in mind?
An alternative would be to provide an argument that works the same as "<defaultLibBundleDir>APP-INF/lib</defaultLibBundleDir>", but does not add the library-directory entry. Or an additional argument to override adding library-directory to the application.xml when using defaultLibBundleDir. The WebLogic-specific argument is certainly not the only approach to accomplish this.
no that's no what I meant. Look at MEAR-151. Everything works as of now but the only difference is that we add an option to generate an empty library-directory element.
I am talking about a separate option. If that works, then we can meet both requests with a single option (yours and MEAR-151). And I also think that "do not write library-directory", "write empty library-directory" and "write library directory with defaultLibBundleDir value" are too many options. It will be confusing.
Thanks
Defining a defaultLibBundleDir path for packaged libs and using a separate option to set the library-directory empty will work. Thanks.
I checked that empty library directory works for my use case with WebLogic too. But only in a way that worries me that these two scenarios don't entirely match up.
Remember that /APP-INF/lib is the older WebLogic-specific magic library classpath and /lib is supposed to be the standardized location since EAR v5.
These are the three scenarios defined according to the Sun XSD:
- Element not present - search in /lib
- WebLogic searches /lib and in /APP-INF/lib and some other special external directories (exploded EARs, generic file overrides, etc.)
- Element empty - disable searching
- WebLogic still searches in /APP-INF/lib and the external directories, but fails to search /lib.
- Element defined - search in given directory
- WebLogic exclusively searches in this directory and ignores all others.
So I think in Sean and my cases an empty element works, but only so long as we stick to the WebLogic specific APP-INF/lib defaultLibBundleDir.
Patch to try to cover all library-directory scenarios from this and MEAR-151.
I don't want to make this any more confusing, but I've now uploaded a patch with a general string parameter to cover any possible required scenarios for library-directory, rather than having to do this in 2 or more boolean parameters.
This defaults to the existing behavior of writing the same value as defaultLibBundleDir, should that be set. It can also be overriden to cover the empty string of MEAR-151, the "not set" of MEAR-146, and the as-yet hypothetical scenario where it has to be some other value.
The use of special magic values is necessary because Mojo parameters unfortunately combine the empty, null and default scenarios for strings. Hopefully it's relatively clear in the generated site doc.
Thanks for the patch Alex. I have changed it slightly to:
- Use libraryDirectoryMode instead of libraryDirectory. I don't like the idea of mixing magic strings with the actual value for the library directory,
- Rename the option to make them shorter and easier to read (DEFAULT_LIB_BUNDLE_DIR is not really easy to put in a pom file): the new values are now "DEFAULT", "EMPTY" and "NONE" (and the case does not matter so you can write this lower-case as well),
- Move the parameter to the right mojo (the main mojo does not need this parameter).
I also added the ITs for the 3 options.
I just deployed a snapshot (2.8-20120827.200901-277). Can you try this out and let me know if that fixes your issue?
Thanks a lot for your assistance, for the details and the patch. This really helped.
I am confused. library-directory is only written if you set the defaultLibDirectory. If I understand you well, you're saying you must use it (to use the magic APP-INF/lib thing) but we should not write the value in that case?
I believe you're asking here to workaround a bug in Weblogic, right. Has this been reported by any chance?