tags:

views:

348

answers:

2

JDeveloper 10.1.3.x

I've recently learned that a library that is not exported will not be included on the classpath when deployed to the embedded OC4J container because it will have no library entry in the application-oc4j-app.xml file.

I have also demonstrated to myself that libraries that are not exported in projects that my project depends on are included in the application-oc4j-app.xml file.

Unexported libraries in my project do not get included. Unexported libraries in my project dependencies do get included.

Is that a bug or a feature, and can I change that behavior such that unexported libraries in my project dependencies also do not get included?

Thanks, Steve

A: 

Unexported libraries should not get included in the application-oc4j-app.xml file. It looks like there is a bug, or some inexplicable behavior in JDeveloper.

IMHO, given a choice between Eclipse or <insert another IDE here>, and JDeveloper, it is wise to choose Eclipse.

One of the inexplicable behaviors that I referred to earlier, was the issue with JDeveloper compiling all projects in the application's directory, even if they were not part of the current workspace file (jws file). In other words, JDeveloper will consider a JPR file for inclusion in the workspace, even if the JWS file states otherwise (i.e. is does not appear visually in the JDeveloper workspace).

Vineet Reynolds
In case I can be of assistance concerning your inexplicable behavior, I have found the cause of something similar in the case where a dependency that is established on another project is persisted even though it is removed from the workspace. It can be confusing when projects not in the workspace are built when you don't expect them to. If you add the child project back into the workspace, you will see the dependency flag reappear in the parent project. You could also probably identify the invisible dependency by editing the parent project file directly as well.
Steven
Ah yes, one of those many things that you will find only by trial and error. I avoid JDev + embedded OC4J for this very reason. It is more productive to use Ant/Maven and deploy the application on a standalone OC4J instance.
Vineet Reynolds
I'm not sure whether your problem has been resolved. Can you please confirm?
Vineet Reynolds
I'm hoping that my resolution is not limited to inexplicable behavior. The problem lies in the fact that log4j is packaged in a third party connector, and my project and dependencies require log4j to compile. They must use log4j from the connector at runtime, but log4j is being included from dependencies even though it is not exported. Either my application is not runnable with duplicate log4j libraries, or it has compilation errors with missing log4j classes. I'm getting around the problem with the "Run Project Despite Compile Errors" flag, but was hoping for a better solution.
Steven
By any chance, is it related to the problem described at http://radio.weblogs.com/0118231/2004/04/29.html#a297 ?
Vineet Reynolds
By the way, the OC4J developer's guide provides info on how log4j needs to be configured for usage in OC4J. More info at http://stackoverflow.com/questions/1341569/using-log4j-in-oc4j-10-1-3/1414966#1414966 .
Vineet Reynolds
The only thing in common between the blog entry and my situation is the participation of log4j. The stackoverflow entry describes a solution to a configuration problem. My log4j usage does not have a configuration problem, nor is the problem solved by adding a global log4j library entry in the jdev.conf file. I've added the line "AddJavaLibFile /c:/Data/Jdev/maven/repository/log4j/log4j/1.2.8/log4j-1.2.8.jar" to the jdev.conf file and there are still compilation errors in the project. No solutions yet.
Steven
I'm not sure if I've got this right, but if your source code and the 3rd party dependency (assuming this is another project) is using log4j, then log4j must be present in both projects unless exported in one to another. At runtime you need not export log4j at all, instead relying on the one configured via jdev.conf primarily because the manner in which the log4j configuration is read.
Vineet Reynolds
The third party software is not a project but a RAR packaged connector that is deployed via .../embedded-oc4j/config/oc4j-connectors.xml. I cannot include its log4j in my project because the connector is itself not a project whose libraries I can export. It's log4j is included on my project's classpath at runtime because of how oc4j deploys connectors. I think the connector and associated libraries are available globally to all projects. I agree that log4j must be available to my project, but therein lies the rub. Even if it is not exported, I get duplicate log4j exceptions at runtime.
Steven
I took a look at your problem description at the OTN forums. Got a better idea of your duplicate class error. The error is due to two classloaders - the application classloader and the web module classloader both attempting to load log4j. The best you can do in this case, is to use an EJB module instead of a servlet to interact with the Attunity connector. Just worth a try.
Vineet Reynolds
The two classloaders is right on. I can remove the log4j library from the web application, and it will run just fine using the "Run Project Despite Compilation Errors" flag, because the missing log4j classes are found in the connector's classloader upstream. What I've been trying to do is include log4j at compile time to get rid of the compilation errors, and exclude it at runtime so log4j can be found in the upstream classloader thus avoiding the duplicate class runtime exception. Turning off the "Export" library flag doesn't do the trick. Any other ideas?
Steven
Also, I am just a configuration manager without control of the projects source code, so making fundamental changes like accessing the Attunity connector from an EJB instead of a servlet is not a call I can make. I'm just trying to make the JDev environment usable for the developers.
Steven
Unfortunately, it doesn't look like you can configure your way out of this. I honestly don't think that embedded OC4J is suited for this kind of a project. You could attempt to isolate log4j from the connector or deploy the connector as a standalone J2C connector instead of embedding it in the application; those are the last tricks in my book. You'll have to summon the JDeveloper gods after that :)
Vineet Reynolds
Thanks for your time. In case anyone else has any ideas, I'd like to leave the question unanswered.
Steven
A: 

To date I have not found a way to specify different classpaths for build vs run time, but with help from a colleague, a solution to my specific situation was stumbled upon. Even though the connector is not a JDev project, the dependent project can reference the log4j jar file that is packaged and loaded with it. That effectively mimics the behavior at runtime, for both standalone as well as embedded oc4j container deployment, in which the web application and associated application code link to the log4j instance loaded by the 3rd party JCA connector's classloader. I did not think this would work assuming that a log4j library loaded by two different classloaders would still appear to be two distinct instances of the library with respect to log4j's static initializers. (That is what I am presuming motivates log4j to throw an exception if it finds another instance of itself in the classloader hierarchy.) Apparently this is not the case, at least for the embedded scenario. I do not have to test this for the standalone container since the Maven build knows not to include a copy of the log4j library jar in the application EAR file via the "provided" scope specification in the build file. The embedded OC4J container now loads the JCA connector, the associated log4 library instance, deploys the application, and allows both to use the log4j classes from the same log4j library file. Not entirely sure of how the connector and web applications classloaders interact, but it works now.

Steven