Will an OSGIfied jar work as a normal jar? - java

I am evaluating the possibility of modifying the MANIFEST.MF files of a set of common Java libraries in order for them to become valid OSGI bundles (by adding the required headers).
Nevertheless, the implications of this aren't clear for me... Will these .jars work seamlessly as the non-OSGIfied ones did in non-OSGI environments?
These jars are being deployed in a range of Application Servers, from IBMs WebSphere to JBoss or Tomcat. Will this OSGIfication trigger an involuntary change in the default behaviour of these applications servers towards these .jars?
And yes, these are jars with external dependencies (on open source projects which might not be OSGIfied) and which also work as dependencies for other projects.

It will have zero effect. The OSGi-ness is only captured in OSGi specific manifest entries; they mean nothing to a plain JVM classloader. In fact, many open source JARs have been made OSGi-ed for some time and you don't need to know it has if you don't use it. One which comes to mind is Javolution

Related

Java War file deployment with a bunch of npm packages

I'm working with a dynamic web project in Eclipse and I'm planning on a Java JAX-RS RESTful back-end with a JavaScript single-page app front-end using a framework of the Angular/Durandal/Aurelia flavor. With that said, the typical way to deploy in the Java world is to bundle things up as a WAR file - which is essentially a JAR file. The trouble is, including the node_modules blows up the size of the WAR file considerably. On the other hand, I can execute 'npm install' after deployment. However, on my development machine, where I'm constantly deploying, that will take too much time. I would prefer if I can prepare the install directory on the web server with the 'npm install' modules and then deploy the WAR file on top of it. The trouble is, it seems the WAR file deployment enjoys wiping out folders if they are not contained in the WAR file.
I'm using GlassFish 4.1 application server. The ideal solution for me would be a way to 'cloak' directory in the WAR file by modifying the MANIFEST.MF file such that when it is expanded the cloaked directories are not overwritten. This would be the most parsimonious solution to my problem. However, I know of no cloaking manifest entries for JAR/WAR file manifest.
There may also be creative solutions arrived at using the 'npm link' command. Any suggestions are welcome.
Perhaps this, among other reasons, speaks to why once people gets started with npm on the client-side they start looking at node and express on the server-side. However, I'm not convinced they can't play nice together and I would like to keep the option of all the old school open source Java libraries at my disposal.
I know this question is almost two years old, but perhaps someone will still need an answer.
Put simply, you need to bundle your JavaScript. You should never be wrapping up your node_modules folder in a war, or even deploying it as-is to the server. Mainly because of exactly the issue you were having. It's... not the smallest.
In front-end development, you're expected to use a tool like webpack to gather up all your JS files into a single app.js file. This process will only take the actual files you directly require or import in your own JavaScript (and the files that those files require, etc), leaving out all the rest. Most importantly for this discussion, leaving out all your devDependencies!
Webpack will also bundle up files other than js. Importing your css files will tell webpack to also bundle those up, creating an app.css file alongside your app.js (though you will need to use an appropriate loader to tell Webpack what it means to import 'main.css').
Getting started is a fairly straightforward matter of adding a config file to your project, adding a new devDependency, and figuring out how to get your Java-based build tool to trigger the bundler. The frontend-maven-plugin, for instance, or the gradle-node-plugin.
These days, webpack and its ilk are even smarter. If your node_modules contains ES6 native modules, bundlers can perform tree-shaking on these files to only bundle the exports that are actually imported. This reduces the bundle size even more.
They can also pull out parts of the bundle into a separate file in order to create, say, a vendor.js file that contains the code for Angular, jQuery, etc. Or you can tell the bundler to treat those imports as external, meaning that they are assumed to have been included elsewhere in the web app. But this is all getting into more advanced features than you need at first. Just give webpack's getting started guide a go, see the difference it immediately makes to your war size, and go from there.
If you are using a nodejs build tool like Grunt (but probably not), then it's likely the devDependencies that's taking up so much space. If so, just copy your runtime dependencies out of node_modules.
If not: you don't have to deploy a .war; you can also deploy an 'exploded' directory. You could copy only changed files and touch .reload
Plus to mentioned above tools to pack NPM resources, let me also mention JNPM: https://github.com/OrienteerBAP/JNPM
It provides maven plugin (jnpm-maven-plugin) to download, filter and pack required NPM packages into your JAR/WAR. So in you case you should publish your client code as NPM package and then pack it into your WAR through this plugin.

Eclipse - checking that all libraries are imported

I have a project that uses a lot of external libraries (mostly .jar files). I am using Eclipse Helios Service Release 2.
When something doesn't work, the problem is usually caused by missing jars or some problem with classpath. What I have to do, is to check that all necessary jars are correctly included in my classpath.
The problem is that I have several libraries imported + external jars (in case of libraries, the classpath only points to the directory with the jars) and Eclipse provides no easy way to search for included jars. If there was any kind of function that would work like this: "search for xyz.jar" and find if the jar with given name is already included somewhere, instead of manually controlling this, it would be a great help.
It would also help if Eclipse provided a function to sort all the jars and libraries by name instead of displaying them in the same order they are specified in path (I mean only in the project manager, of course).
So my question: is there an easy way to check these things or do I have to do that manually? I have cca 30 jars to include and cca 300 already there and this is a real pain...
You could use a build environment, such as Maven, to manage your dependencies for you. Then Eclipse does zero thinking on its own and your life becomes far more pleasant (particularly when the time comes to package your code for release).
I couldn't imagine managing 300+ dependencies any other way.

classpath issue with jar files

I'm having a classpath issue with commons-httpclient.jar.
The application uses a newer version of the commons-httpclient.jar, which is commons-httpclient-3.0.1.jar.
Once JBOSS is installed it installs the original version named commons-httpclient.jar in two different directories.
/opt/appname/lib and /opt/appname/server/default/lib
It would be easy to simply remove them, but it turns out that they are being used by another application on the system. I would like to know if there is any way to designate an order to which classes are used, for example.
Use commons-httpclient-3.0.1.jar first then use commons-httpclient.jar
Fairly new to Java, so any help would be appreciated.
I believe the only way to do this under the constraints you mention is to move the right JAR into the server/default/lib folders of each of the apps on your JBoss, and remove it from /opt/appname/lib.
That said, this may still be problematic, as JBoss itself may also need the JAR. In that case, you may be out of luck.
As a side note, you can create a folder /jboss/lib/endorsed. Libs placed there take precedence over those is jboss/lib.

What method/class etc. uses this .jar?

I have a big application as an enterprise scale, there are lots of developers working on it; it is a Java Spring app, we use Eclipse as development environment. We have lots of libs, which means jar files in the lib directory. I can't touch to these jar files so easily, because whenever I change some jars, application may get failed/unstable because of little changes of the jars' new versions. On the other hand, as this application is a big and old project, I can't know what jar is really needed and which line, what function or class uses/needs this jar exactly.
So I have a problem now: As an example naming a-lib-1.0.jar is old jar and a-lib-2.0.jar is new version; I need to use a-lib-2.0.jar but a-lib-1.0.jar is already in lib directory. How can I know that a-lib-1.0.jar is needed or not without testing by deleting it?
And how can I find the line/method which uses this jar?
Please check Tattletale from JBoss.
What you need is a Dependency Walker.
Try this:
http://www.dependency-analyzer.org/
http://depfind.sourceforge.net/

Whats best way to package a Java Application with lots of dependencies?

I'm writing a java app using eclipse which references a few external jars and requires some config files to be user accessable.
What is the best way to package it up for deployment?
My understanding is that you cant put Jars inside another jar file, is this correct?
Can I keep my config files out of the jars and still reference them in the code? Or should the path to the config file be a command line argument?
Are there any third party plugins for eclipse to help make this easier? I'm using an ant build file at the moment but I'm not sure I know what I'm doing.
Is there an equivelent of the deployment projects in Visual studio, that will figure out everything you need and just make an installer? I've used install4j before, and it was powerful if no where near as automated as .Net deployment projects.
Cheers.
There is no one 'best way'. It depends on whether you are deploying a swing application, webstart, applet, library or web application. Each is different.
On point 2, you are correct. Jar files cannot contain other jar files. (Well, technically they can, its just that the inner jar file won't be on your classpath, effectively meaning that jar files do not contain jar files).
On point 3, you certainly can reference config files outside the jar file. You can typically reference a config file as a file or a resource. If you use the resource approach, it typically comes from the classpath (can be in a jar). If you use a file, then you specify the filename (not in a jar).
In general, most Java developers would use Apache Ant to achieve deployment. Its well documented, so take a look.
(1) An alternative to ant that you may wish to consider is maven.
A brief intro to maven can be found here.
For building a JAR, maven has the jar plugin, which can automate the process of ensuring all dependent jars are listed in your jar's manifest.
If you're using eclipse, then download the maven integration as well.
(2) Another alternative is to use OneJar (disclaimer: haven't tried this myself).
The answers vary depending on what kind of thing you're building.
If you're building a library, it's best to distribute your work as a jar file. It's possible to refer to your jar dependencies via the Class-path attribute in your jar manifest, although I generally think that's uncool. That attribute was designed for applets and it's used infrequently enough in libs that when this technique pulls stuff into the classpath (particularly common stuff the user might already be using), you can get unexpected version conflicts. And it's hard to track down why you're seeing them.
Publishing a jar to a Maven repo with pom info to track dependencies is an excellent choice for libraries as well. If you do that, please publish your Maven coordinates in your docs!
If you're building an app, the two popular choices are to distribute a zip/tar/whatever of a deployment structure OR to use an installer program. If the program is a server-ish kind of thing, the former is far more common. The latter is more common for clients. Generally, the installer program is just going to lay out the deployment structure and maybe do some extra tasks like installing in OS-specific locations.
To build your deployment structure (aka "kit") you'll want to create a repeatable process in whatever build system you're using. Ant has copious examples of this and Maven has the assembly plugins that can help. Generally you'll want to include a jar of your code, any dependencies, scripts to start the program, maybe a JRE, and any other resources you might need.
If you want to create an installer, there are many options both free and commercial. Some folks I know have recently had good experiences with the free IzPack but check out your options.
You should try FatJar. It's an Eclipse plugin that with just a right click at the Project can build a JAR file with all you need to run the application, including the necesary third party JAR.
We use it everyday, in conjuction with JSmooth to create the executables, to deploy our software packages to our customers, and works like a charm.
Well, if you are speaking of deployment of a standalone desktop application:
Before we switched to web start we have been creating three deployment archives, one for windows, one for mac and one for other platforms.
On windows we have successfully used the Nullsoft Scriptable Install System (known for it's usage by the older winamp versions) and its ant task, although some drawbacks are:
It is only usable on windows AFAIR
You have to do some work by hand, i.e. customizing the wizard-created script AFAIR
It can create a windows installation with start menu entries on the other hand. There also exists an eclipse plugin for integrated NSIS shell script editing.
On Mac OS X there is an ant task to create an .app file from your java files so that you can start it like a native os x application. But beware of not writing any setting to your home dir and using the the application dir instead.
For others you have to expect they are in a un*x env and deploy your app with a shell script to start the application.
In any case you may have to deploy your custom policy file to get access rights for your application.
If you want to get rid of all the packaging and stuff you should seriously consider using web start. We have saved much time since switching to it, i.e. simplified our deployment process, takes care of updates etc.
Update 2014
Use maven assembly plugin, see section "Creating an executable jar"
Ant. It's not the best thing in the world, but it's standard, it's apache, and it works.
There's some good examples on the web how to make a simple build.xml for any, and it's got some features like the 'war' task that knows how to put all the basic stuff (classes, web.xml etc) in the jar file for you.
You can also tell it to pick up other config files and jars and it will happily do it.
It's also really smart about what to compile. You give it a directory, and it finds all the java files and builds them only if their classfile is out of date, so you get some of the traditional make functionality for free without much effort.
You could look at other java projects (e.g. JMeter, SquirrelSQL, JEdit, Cernunnos, etc.). Each package their applications slightly differently, so consider your goals when you review these.

Categories

Resources