Is there a way to include environment specific properties or configuration file while building war.
QA
entity.url=http://qa.test..
prod
entity.url=http://prod...
I need to make around 5 to 6 REST calls. Url is different for each environment. Hence is there any way to configure environment specific conf file?
thanks in advance
The Play Framework has the concept of 'ids' that can be used for different modes see here:
http://www.playframework.org/documentation/1.2.4/ids
This allows you to do:
%qa.entity.url=http://qa.test..
%prod.entity.url=http://qa.test..
The one thing that might not be clear by their documentation is how to set this in a war. When running as a .war file, the play ID is set to 'war' by default. This can be changed in the web.xml of the .war file. You can do that or you can specify the ID when you create the war:
play war -o PATH --%prod
Not that I am aware of (and reading the python source for building the war does not indicate this is available). The war file simply builds up your Play application, as is. If you want to have a different configuration, then this may simply require the loading of it from an external resource (a property file that lives outside of the WAR, that you ship with your WAR file).
Alternatively, you could modify the python script that builds the WAR file to custom add additional properties to your file. Look in the directory framework/pym/commands/ and look at the war.py to read the source for the python war command.
Related
I have an executable jar with a war file in it. Running the jar extracts the war file and creates a WebAppContext from it using webAppContext.setWar(warFile). Although that works, it seems that webAppContext.setWarResource(warResource) should work. I've tried it creating a resource using new PathResource("file.war") which shows a path like "jar:file:/Users/.../jetty-1.0.0-jar-with-dependencies.jar!/file.war". Sounds promising and conventional, but when I try it I get "java.lang.IllegalArgumentException: not file: scheme". Do I really have to extract the war file or is there a trick?
That would be a nested jar content reference and no Java program can do that.
Option 1: use a live-war (aka an executable-war) instead.
This would be a war file that can be deployed traditionally if you want to, but can also be used standalone from the java command line (and will start it's own server if it needs to).
An example project is maintained by the Eclipse Jetty project at ...
https://github.com/jetty-project/embedded-jetty-live-war
Note: the live-war concept was inspired by work done by the Jenkins project and their live-war.
Option 2: eliminate the WAR file layer entirely in your JAR
Don't package the WAR contents in your JAR as a filename.war, consider using it as an exploded WAR (or war directory) instead.
Just unpack the WAR into your JAR file somewhere safe (like /META-INF/webapps/<app-id>/) and then reference that directory location in your JAR file instead.
Option 3: eliminate the need for the WAR concepts entirely
This is the number one most popular choice.
You deconstruct your WAR file into a ServletContextHandler with configured Servlets and Filters, this also eliminates the need for things like annotation scanning / bytecode scanning (which is quite complicated), you'll also not have to wrangle the nested / isolate classloader (your uber JAR file contains all of the classes and downstream dependencies needed to run your webapp), and this approach will definitely speed up your startup time.
Is it important how a war is called? Does it have any effect on whether it will work correctly? Let's say you're building a war with maven, naming it in one way and then manually rename it to some other name before deploying it somewhere on a server and running it, would it have any effect on working? Like deploy issues, etc?
Let's say with the maven war plugin you set it to generate something.war and later rename it to newfilename.war before deploying. What is your experience/knowledge there?
The name might matter depending on the servlet container: tomcat uses the name of the war file without the .war extension as the context path. This can be adjusted though using container-specific configuration files inside the .war file.
Obviously it would also matter in that case when you're trying to access it.
How I can set a war in an embedded jetty in a way that it can load from a classpath. Following is my current code snippet
webAppContext.setWar("hello.war");
Context :-
I want to secure my code other than obfuscation.so, I used Jetty to create a runnable jar and subsequently i used winrun4j to create an exe wrapper. The exe works fine when war file is found at same level but not otherwise even though i've embedded the war in winrun4j exe.
Problem:-
Is there any way that i can set the war in a way that it can pick it up from classpath rather than some pre-defined path.
Hope i communicated the problem statement in a lucid way.
Thankyou.
I came around the same and I always extract the war to a temporary location and then use the absolute path;
webAppContext.setWar("/path/to/temp/tmp262622522.war");
In any case Jetty will extract the war to a temporary location too, when starting the web app.
I'm currently working on an internationalized webapplication in java, using only the standard servlet api (no frameworks). for all static text on the pages like headings, labels etc. I've been using the fmt tag library, backed by properties files in WEB-INF/classes.
the application is almost done, but the requirement that our client might like to change or update the translations later on, has suddenly been introduced.
Since the properties files are located inside the war, this is not doable without recompiling the app. so, my question is simply: is there any way of updating the properties files inside the war or maybe have the setBundle tag load the files from an external directory. or maybe a third, more clean and correct way to achieve this?
A war is just a zip file. Unzip it, change the properties files, and rezip. No need to recompile anything.
Providing a simple script to do that in a single operation should be easy. You could even use the u (update) option of jar to do it. See http://download.oracle.com/javase/tutorial/deployment/jar/update.html
Put them in an external folder and add its path to the webapp's runtime classpath. For example, /var/webapp/conf. As to adding this path to the webapp's runtime classpath, this depends on the server used. If it's for example Tomcat 6/7, then you need to add it to the shared.loader property of Tomcat/conf/catalina.properties file.
shared.loader = /var/webapp/conf
This way it's available in webapp's runtime classpath the usual way and you don't need to repackage the WAR..
I am developing a framework that needs a lot of stuff to get working. I have several folders inside of my Eclipse project that are needed
[root]
- config
- src
- lib
- serialized
Also there are important files like the log4j.properties and the META-INF dir inside the src directory.
I wonder if there is a way to distribute one JAR containing all essential files so my gui will just have to import one jar. I guess that I have to exclude the config folder in order to make the framework configurable.
I also wonder, if there is a way to move for example the log4j.properties to the config dir so that I have one config folder containg all needed configurations?
Thanks for help and advise on this matter!
Marco
Yes, but not really. You can take all your dependencies, unpack them and simply merge them into a bigger jar. This is what the maven jar plugin does if you make a jar with dependencies. The only problem is that this might result in conflicting files (suppose two of your dependencies contain a log4j.properties). This is one of the problems when doing the above with some of the spring libraries for instance.
I think someone actually wrote a classloader that allows you to bundle the whole jar inside of your jar and use it as is. I'm not sure how mature that is though and can't at the moment recall the name.
I think you're better off distributing all your dependencies separately. Setting up the classpath is a bit of a pain but surely java programmers are used to it by now. You can add dependencies to the Class-Path header in your manifest file, in simple cases. Bigger libraries have to rely on the classpath being set up for them though.
As to the second part of your question, probably dropping the conf/ directory under META-INF is enough for its contents to be picked up. I'm not sure about this. I'm fairly sure it will always be picked up if you put its contents at the top level of the jar. In any case, this is a distribution problem. You can easily have a conf/ directory inside your source tree and have your build scripts (whatever you might be using) copy the files in it to wherever is most convenient.
As to your users configuring. Try to establish some conventions so they have to configure as little as possible. For things that must be configured, it's best to have a basic default configuration and then allow the user to override and add options through his/her own configuration file.
In terms of the resources, it is possible except that if you do that you are not going to be able to load resources (non class files) from the filesystem (via a file path).
It's likely that you're currently loading these resources from the file system. Once in the jar you need to load them as class path resources via the class.getResourceAsStream or similar.
As for the dependent jars you may have, it's common practice for these to be placed as extra jars on the classpath. I know it's complicates things but developers are used to doing this. The nature of the java landscape is that this is inevitable. What the spring framework for example does is supply a bundled zip file with the core jar and the jar dependencies included.
Is your library going to be used in an EE context or an SE context? If it is an EE context then you really don't have to worry about configuration and class path issues as the container takes care of that. In an SE context it is a lot more tricky as that work has to be done manually.