The size of my EAR file has reached around 100 MB after adding many exetrnal jars.
Environment : Java Spring/Websphere application server/Maven
Please share the tips to reduce the size of an EAR file.
Seems the exteral jars contribute most to the large size. Is it possible to follow an approach like below, if so how to do that?
Do the maven build with compile scope for large jars
Keep the large sized jars in app server lib, with this will the app take these jars at runtime from appserver?
Thanks
Smitha
You should really review your jars, especially poorly done Maven builds add a lot of unnecessary jars to the application (like jta, servlet, jee-api, etc..), so make sure you don't have them. Sometimes jars are duplicated in every web module you have in the EAR.
Second WebSphere is Java EE 6 server, so it provides lots of common features like JAX-WS, JAX-RS, JPA, etc..., so you should consider using them, before throwing all that as third party libraries in your application.
If you want to use shared library approach, do not put the jars in the server lib folder or server classpath. This is not recommended.
Create Shared library via Environment > Shared libraries see here and assign them to the application.
To reduce the War size you can consider
Static Content :Keep the Static content like images etc out of the war file and refer them via application using references to location.
Shared Libs : if majority of the size is contributed by Shared Libs you can separate that out of war. to do that you can place the war libraries in one of the following locations
a) In Server Lib folder, Not Recommended since different apps might use diff versions.
b) In Server App Lib Folder
b) In a shared folder and including that folder into class path .
c) Use exploded war deployment deploying only changes.
Related
I have deployed the one ear inside the dropins folder and one of the war file from the ear is referencing the jar which i kept outside folder (Shared->config->lib->global). External jars which i kept global folder is again referring few jar which resides in the ear and this time i am getting "java.lang.NoClassDefFoundError"
Can you please suggest how to give reference .
server.xml
<webApplication contextRoot="/xyz" id="zyx" location="xyz.ear" name="xyz" type="ear">
<classloader commonLibraryRef="global,filterjars"></classloader>
</webApplication>
Common shared libraries cannot load classes from application binaries. When using common libraries, you can think of them as a one-way connection.
The application's classloader can delegate to common shared libraries, but not the other way around.
Common libraries are implemented as their own classloader so they must contain all dependencies.
On the other hand, private libraries have their classpaths appended to the application classloader's classpath - so they could load classes provided by the application, but this is not a good practice. For example, if a private library depends on ClassA that application1 provides, it will work just fine for application1, but might break in application2 that might not provide ClassA (or might provide an incompatible version of it).
If you have classes in your shared libraries that depend on classes in your application, I would either recommend putting all of those classes in the shared library - or putting all of the shared library classes in the application (or WAR, etc.). I personally prefer the latter - self-contained applications are much more portable and less likely to run into classloader/dependency issues (i.e. app1 needs version X of some dependency, but app2 needs need version X+5...).
Hope this helps,
Andy
I am working on a large scale system using PrimeFaces 5.0, Java EE 7, Maven 3.0.5, Netbeans 7.4 & GlassFish 4.0
I want to implement it as (multiple WARs , multiple EJBs , one EAR).
Multiple wars could have common files like (JS, CSS, XHTML, Backbeans & Converters)
i have achieved this using jar which contains this resources.
different WAR files, shared resources
I need a session-scoped bean to be shared between different wars, I found this but i found it more than what i need.
http://docs.oracle.com/cd/E18686_01/coh.37/e18690/glassfish.htm#CEGBDHJB
so my questions is:
Is using a jar is the right approach to share what i want ??
where do i put jars like primefaces or omnifaces in the project where they use the same class loader ??
How can i share session-scoped between different wars ??
I have been working on a ear project with similar requirements as yours, according to our experience :
Sure. We have seperated our war projects and use them as extended controllers to carry out front end logic and passing data to view, and they make their service calls via a jar file called common-services.jar . Our whole service layer is living on a single jar file. However if you ask my personal opinion, I think it would have made a lot sense to create a third war file just for the services, and talk restful with all the front-end repos. That way service calls could be opened to third party users without any further work. So to sum it all up, yes it is an acceptable approach, but you should also consider packing it as war.
On a parent pom above all war, so all war files use the same version and it is managed from a single pom.
Carry all session based operations to your third jar / war we have discussed in question 1. Makes much more sense that way. Or I suppose you will need solutions like single sign on. But my first suggestion works like a charm for us.
We've multiple wars being deployed on one server.
The CSS, JS, images, ... are mostly common for all war files.
What is the best way to serve these resources?
Options I've found so far:
Use Maven Overlay plugin (This causes us to loose flexibility of hot-swapping resources in our IDE)
Create a common jar to package in your war (needs Servlet 3.0 api if I'm correct)
Create a war file that contains only resources and that can be deployed on the server as well
If you have may users, then a content delivery network would be an appropriate way to deliver the static files.
I have a project with more than an hundred external library dependencies, here we use tomcat with this endorsed jar libs configured on a directory in the server (now is under $CATALINA_HOME/lib/endorsed), so the webapp can access those resources on runtime start.
I wanted to try jetty instead, because tomcat takes too much memory and crashes frequently. Now I'm wondering if there is a parameter to pass on maven-jetty-plugin to specify this jar's folder so as the webapp class loader find them in its classpath.
I've tried extraClasspath in configuration tag, but it seems to load only classes and ignore all jars in the directory I set into (if I pass the full name path of the jar, it is loaded, but I don't want to set every library that I need there).
Thanks in advance for the help
update:I know it's not a standard maven operation, i'm searching for an emergency workaround since this project is very huge and I can't refactor as I want.
But also I expected this feature was not as tricky as it seemed to me at first glance.
You need to pass them as absolute paths, or, alternatively, have them as dependencies of the plugin itself.
What you want to have done goes against Maven's portability principles, so don't expect it to support it.
I have an issue in loading jars in websphere server. Some of the jars are present in WEB-INF/lib and some are present in local hard drive(ex., c:\lib folder). How can i load all these jars, during the startup of the application. If WEB-INF jars are loaded, external jars are not getting loading and viceversa..Need help on this....
WebSphere has a hierarchy of classloaders, parent classloaders cannot see child classloaders, hence you get surprises when you put different aspects of your application in different places.
Never attempt to place application jars in WebSphere's own lib directory, and never adjust WebSphere's own class path. There is ana rchitected way to make external jars visible, I'll explain that in a moment.
There are three places that you can put JAR files so that they will be loaded. By far the the best is simply to place the JARs in WEB-INF/lib. You can specify the search order preference PARENT LAST so that these take prececdence over jars supplied by websphere - but note that some fundamental jars cannot be over-ridden You cannot replace the IBM security for example.
Second you can add jars to the root of the EAR file. Noe that the hierarchy comes into play now, WEB-INF/lib jars can see EAR jars but EAR jars cannot see WEB-INF/lib jars.
Finally you can specify a WebSphere "Shared Libarary". See the Info Centre for how, it's very easy through the console. A shared library has a classpath, you add jars to that. Then you allocate the shared libarary to individual applicaitons or whole servers.
Once again You WEB app can see the shared library, but i don't beleive taht the convers is true. Hence putting framework code in a shread library may not work for you.