In my source code, I'd like to get programmatically, the last modified date of the current EAR from which my code is deployed.
I'm using Oracle WebLogic.
How could I do that?
Thx for your answers
I'd suggest stepping back and looking at the problem you're trying to solve, Eric.
Do you want to know when the application was built or the particular version of the application you've got deployed? If that's the case, you're probably best served by incorporating something into the build process to set this. Ideally a manifest of the specific component versions used to package up your application.
If you want to know when the application was first deployed by an administrator, or most recently deployed that gets more tricky. Relying on the filesystem to solve this problem is a bad idea because you're at the mercy of whatever WebLogic Server is doing, which is admittedly more than a bit opaque.
If you absolutely need to do this, WebLogic Server's standard staging behaviour puts a version of the file in a particular subdirectory on each server instance, then very quickly pulls it apart. (it's the 'servers//stage' subdirectory underneath the root directory of the domain ($DOMAIN_HOME) $DOMAIN_HOME is the current directory for all server processes at runtime, so the relative path should work fine.
That should give you the time that file was deployed across the network, but you'd definitely want to test the observed behaviour from rebooting your server instance.
The problem with that is that it doesn't give you anything you couldn't determine more elegantly via either the build process, or WLST scripting around the deployment process.
If it's the last time the application itself was deployed (regardless of the version) then application lifecycle event listeners are definitely the best way to go. Unfortunately there's no MBean that gives you the uptime of an individual application.
There's a great reference on lifecycle listeners here:
http://download.oracle.com/docs/cd/E17904_01/web.1111/e13712/app_events.htm#i178290
You could either check the file properties or see inside the MANIFEST.MF present inside the EAR.
Related
Massively messed up production issue:
I have inherited a massive ( 1 million line code base ) web application that my predecessors botched up completely.
They thought it would be a wonderful idea to just add the WEB-INF/classes directory the the system classpath in the startupWeblogic script instead of properly packaging up the application in an ear or war file, and manually point all the paths in the console to the various non-standard paths they just conceived of themselves.
Now my problem is I have to install another application as a proper war file that uses classes with the same packages and names, just even older code, into the same Weblogic 10.3.6 instances. But as you can imagine the stuff that is hacked into the system classpath takes precedence over everything in the additional webapp, even with the prefer web app lib preference set in the weblogic.xml file.
Notes:
Repackaging the offending application is not an option on my timeline, it is going to be done, but just not in the timeline I have to meet. Running on other instances of Weblogic isn't in my timeline either, I don't have the time to go through the provisioning process to get the assets in time.
Given this how can I get this additional webapp to play nice and deploy in the same weblogic instance as the one that is hacked into the system classpath.
If someone can give me an answer that solves this issue, I will make sure to put a massive bounty on this when I am able to and award it to you after the fact. The sooner the answer the bigger the bounty will be!
Did you try prefer-application-packages within the weblogic-application.xml as well?
The mechanism that Weblogic calls the Filtering Classloader, here are the links:
http://docs.oracle.com/cd/E15051_01/wls/docs103/programming/classloading.html#wp1097187
http://hasamali.blogspot.in/2011/08/weblogic-identifying-class-conflict-and.html
http://atheek.wordpress.com/2011/12/20/weblogic-filtering-classloaders/
I have a webapp in a war archive which is deployed on cloudfoundry.
One of the libraries ("somelib.jar") used by the app is made by another developer.
I would like a way for him to upload several different versions of somelib.jar and test the behaviour of the app.
I have managed to get the jar uploaded to WEB-INF/lib directory of the deployment. I have also managed to unpack the jar into WEB-INF/classes. However, I have not managed to get the new version of the jar to be used. I tried various hacks such as those described in this question and this question without any luck.
Everytime, the classes/jars that get loaded the first time get used after that, even if we replace the actual .class or .jar file in the above directories.
Is there any easy way to achieve what I want?
Note: Since I dont have control of Tomcat (where it runs), I cannot configure Tomcat or make any changes to the server. I just have control on my war file, so everything needs to be done programmatically.
EDIT: the reason I want this is to reduce our testing time. Currently someone gives me a new version of somelib.jar, I repackage it into my application, upload to CF, send him a notification, then he tests the behavior of the new jar. What I would have preferred is that he upload his jar directly to CF and do the testing whenever he has a new version without the unnecessary intermediate delay.
In tomcat 7, you can version your WAR file and the new versions will gradually kick in.
http://www.tomcatexpert.com/blog/2011/05/31/parallel-deployment-tomcat-7
In order for you to control the application server yourself, you would need to deploy a standalone app into Cloud Foundry.
This blog should help you out with that:
http://blog.cloudfoundry.com/2012/05/11/running-standalone-web-applications-on-cloud-foundry/
This way you can custom configure your tomcat.
Everytime, the classes/jars that get loaded the first time get used after that, even if we replace the actual .class or .jar file in the above directories
That's the way that normal Tomcat (Java EE) classloading works. Your classes are loaded when first deployed, and any changes will be ignored (JSPs are managed slightly differently, but only in a development environment).
You should be able to solve this problem by using the Equinox OSGi bridge servlet. I haven't done this myself, but here's a writeup by a person that I respect.
I'm trying to configure logging for my web application (WAR), in log4j.properties:
log4j.rootCategory=WARN, RF
log4j.appender.RF=org.apache.log4j.RollingFileAppender
log4j.appender.RF.File=???/my-app.log
What file path I should specify for my-app.log? Where to keep this file? Currently I'm deploying my application to Tomcat6, but who knows what happens in the future. And who knows how exactly Tomcat will be configured/installed on another machine, in the future.
What I finally did is this:
In continuous integration settings.xml I define a property log.dir
In log4j.properties I define: log4j.appender.RF.File=${log.dir}/my-app.log
In pom.xml I instruct Maven to filter .properties files
That's it. Now I can control the location of my log files on the destination container without any changes to the source code.
Logging is a deployment configuration descriptor so you really cannot generalize. Configuration depends on the host machine and other, non functional requirements of the project.
Generally in tomcat I log into ${catalina.home}/logs/myapp.log but as you can imagine if I deploy in weblogic there isn't any catalina.home so the log will go to c:\logs\myapp.log.
I agree with #cherouvim. In general, you should put the log file outside of the webapp, and preferably in the same place that the container puts its log file.
You don't want to put them in the webapp tree, because they will get clobbered if your webapp is redeployed.
What file path I should specify for my-app.log? Where to keep this file?
If the question is about your personal machine, it doesn't really matter. Put them where it's handy for you (e.g. next to the server logs).
If the question is about a development, IST, UAT, etc environment, logs should typically be written to a separate/dedicated partition. But you should ask this question to the sysadmins, many companies have exploitation standard, standardized layouts.
Currently I'm deploying my application to Tomcat6, but who knows what happens in the future.
This is a shot in the dark since but here is a normalized path I've used in the past: /var/log/tomcat/<PROJECTNAME>/myApp-<instance-#>.log.
And because I'm not better than you at fortune-telling, yeah, who knows what happens in the future :)
And who knows how exactly Tomcat will be configured/installed on another machine, in the future.
That's the beauty of a configuration file, you can configure it as required... and even change it :)
I am just investigating the idea of this so have no example code. I've been digging around on the web but I'm not really sure what I should actually be looking for so I'm not finding much. So I thought I'd ask and see if anyone knew if a) This is possible. b) How I should do it. (Or at least what I should be looking to learn about to do it.)
I'm building a web app using JSP pages on the client with a JBoss server running J2EE, in the middle there is a tomcat web server.
Basically the app contains different sections that will be rolled out over time as they're developed and also customers may be using different combinations of sections. The tidiest way of deploying this I can think of is to build each section into it's own jar. Then depending on the combination of sections that are relevant for the customer, install only the required jars on the JBoss server for deployment.
To support this I'd like the client navigation menu to only show the available sections based on what is deployed on the JBoss server. Is it possible for my servlet to find out what is deployed on the server? I'd like the solution to be as 'dumb' as possible, i.e. I don't want to tell it what to look for, (other than a prefix to identify our jars), as I don't know yet everything we might build.
My current solution is to have a table in the database to hold a list of the installed sections. But this is going to require update scripts etc during install and I'm sure we should be able to do this by just deploying jars on the server.
Thanks in advance.
You could add this information to the MANIFEST.MF file and then enumerate all files in your webapp (see this answer for how to list all manifests) when you start.
I do something similar by configuring a "Plugin Directory" setting for my application. It then scans that directory regularly for Jars. It looks for specific metadata in the manifest to determine whether the Jar is actually a valid plugin, and what class to load from it (the static initializer of that class registers the plugin with the application).
Then all you need to do is place a new Jar into that directory to add its functionality.
I'm learning Servlets programming, using Apache Tomcat 6 on a Ubuntu 8.10 machine, and I'm running with a very annoying issue -- apparently, related to caching.
This is what I'm doing: I write a servlet, put it in a nice directory structure and deploy it using the Tomcat Web Application Manager. It works as expected. Then I edit the servlet, recompile and try to access it again, but Tomcat keeps returning the same old version. Reloading the Application or even restarting the server does not work. The only thing that works is "Undeploying" the Application, then deploying it all over again.
I have to do this every single time I make any small change on my code. It sucks.
I'm sure there is a way around this, but I couldn't find the answer anywhere on the web (and I did search a lot). I would really appreciate any help. Thanks!
The advice from Adeel Ansari is flawed: you should never modify CATALINA_HOME/conf/context.xml with webapp-specific configuration. That's what your-webapp/META-INF/context.xml is for.
You should also never specify the "docBase" attribute of <Context>.
You should also never specify the "path" attribute of <Context>.
The OP has several options:
Use the manager to reload the web app (undeploy/redeploy should not be necessary: a simple reload should work)
( http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Reload_An_Existing_Application )
Set the element in META-INF/context.xml to have reloadable="true"
( http://tomcat.apache.org/tomcat-6.0-doc/config/context.html )
With all due respect to SO, if you need help with Tomcat, join the users' mailing list and get some real answers.
I have encountered similar problems with Tomcat 5.5. I never figured out the root cause but I worked around it by deleting the folder corresponding to the webapp from %CATALINA_HOME%/work/Catalina/localhost. Its not a great solution but it avoids you having to undeploy/redeploy your whole application.
Under your TOMCAT_HOME/conf/, you will find a file named Context.xml. The content would look like below,
<Context>
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/classes</WatchedResource>
</Context>
Both lines are uncommented here, you should uncomment both too. Its likely that you will have the 2nd one commented or might not have it at all. Try uncomment it, or add it in latter case. I am assuming you are deploying your app under TOMCAT_HOME/webapps.
[Edited]
Try using docBase, and path attribure under your Context element. Below is the example
<Context docBase="path-to-WEB-INF" path="/your-app">
NOTE: Don't include WEB_INF
[Edited]
May be I am missing something. Check this out. Its the same, but much more clear and descriptive including few other options.
You don't say if you are using the ubuntu tomcat or a separate download from tomcat.apache.org. If you are using the ubuntu one, try to make it simpler with using a separate download. The standard download is very easy to administer and rather geared to working out of the box. It might be (I don't know) that the ubuntu one might be configured more towards production use, e.g. it might be somewhat hardened.
The recommended production setting for tomcat is just what you describe (e.g. no auto-deploy etc). The development setting is way easier to use.
If you use Netbeans then it automatically recompiles the class and injects it into the running webapp when you save the file. There are no additional steps involved, just hit save.