You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Douglas Ferguson <do...@epsiia.com> on 2006/08/23 00:19:30 UTC
Jar With Dependencies
Does anybody have a suggestion for creating a jar with dependencies that has all the dependencies exploded?
We have a module that is a composite of a bunch our other modules, the purpose of this is for our client who are using java integration rather than web integration.
If I send them a jar with dependencies, then they would have to crack the jar open, because the classloader won't read a jar within a jar.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Jar With Dependencies
Posted by Arnaud Bailly <ab...@oqube.com>.
Arnaud Bailly <ab...@oqube.com> writes:
Oops ! Did not mean to clutter the list with code, sorry.
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
RE: Jar With Dependencies
Posted by Douglas Ferguson <do...@epsiia.com>.
Ah.. that's nifty.
However, this is not a console app. These are our java apis that we are sending the client. They need to add this jar to their classpath.
Here's a simplified example what we have:
Common.jar
Persistence.jar
WSA.jar
Client.jar
Where Client.jar is just a composite module with dependencies on Common, Persistence, WSA.
I think the trick is to use the assembly plug and set unpack to true.
However, if someone else knows another trick.....
D-
-----Original Message-----
From: Arnaud Bailly [mailto:abailly@oqube.com]
Sent: Wednesday, August 23, 2006 8:38 AM
To: Maven Users List
Subject: Re: Jar With Dependencies
Douglas Ferguson <do...@epsiia.com> writes:
> Sure, I'd love to see that script.
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Lanceur implements Runnable {
private static final Log LOG = LogFactory.getLog(Lanceur.class);
/*
* the command line arguments array
*/
private String[] arguments;
/*
* the exit status
*
*/
private int status = 0;
/*
* class loader constructed by this lanceur
*/
private URLClassLoader loader;
public static void main(String[] argv) {
if(argv.length == 0)
System.exit(1);
/* first argument is real lanucher class */
String real = argv[0];
Class realC = Class.forName(real);
/* shift les arguments */
String[] nargs = new String[argv.length - 1];
if (nargs.length != 0) {
System.arraycopy(arguments, 1, nargs, 0, nargs.length);
}
Lanceur l = (Lanceur)realC.newInstance();
l.setArguments(argv);
l.run();
}
public void run() {
/* extraction du repertoire */
String libdir = System.getProperty("libdir","..\\lib");
if (libdir == null) {
LOG.error("Definir le repertoire contenant les bibliotheques : -Dlibdir=<xxxxx>");
setStatus(1);
return;
}
/* verifications */
File f = new File(libdir);
if (!f.exists()) {
LOG.error("Le repertoire" + libdir + " n'existe pas");
setStatus(2);
return;
}
if (!f.isDirectory()) {
LOG.error(libdir + " n'est pas un repertoire");
setStatus(2);
return;
}
if (!f.canRead()) {
LOG.error("Le contenu de " + libdir + " ne peut etre lu");
setStatus(2);
return;
}
/* extraction du nom de la classe principale */
String clname = System.getProperty("main","Main");
if (clname == null)
clname = "Main";
/* construction du classpath */
File[] jars = f.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().endsWith(".jar")
|| pathname.getName().endsWith(".zip");
}
});
int ln = jars.length;
URL[] urls = new URL[ln + 1];
/* ajout du repertoire courant par defaut*/
try {
urls[0] = new URL("file://.");
} catch (MalformedURLException e) {
LOG.error("Impossible d'ajouter . au classpath : "
+ e.getLocalizedMessage());
}
for (int i = 0; i < ln; i++)
try {
handleJar(jars[i]);
urls[i] = new URL("file://" + jars[i].getPath());
} catch (MalformedURLException e) {
LOG.error("Impossible d'ajouter . au classpath : "
+ e.getLocalizedMessage());
}
/* chargement */
loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
try {
Class cls = loader.loadClass(clname);
Method main = cls.getDeclaredMethod("main", new Class[] { nargs
.getClass() });
LOG.debug("Execution de "+clname +".main(");
for(int i=0;i<arguments.length;i++) {
LOG.debug(arguments[i]);
if(i < arguments.length -1)
LOG.debug(','+"");
}
LOG.debug(")");
main.invoke(null, new Object[] { nargs });
} catch (ClassNotFoundException e) {
LOG.error("Impossible de trouver la classe " + clname
+ " : " + e.getLocalizedMessage());
setStatus(3);
} catch (SecurityException e) {
LOG.error("Erreur de securite pour charger la methode main dans "
+ clname + " : " + e.getLocalizedMessage());
setStatus(3);
} catch (NoSuchMethodException e) {
LOG.error("Impossible de trouver la methode main dans "
+ clname + " : " + e.getLocalizedMessage());
setStatus(3);
} catch (IllegalArgumentException e) {
LOG.error("Argument incorrecte a l'execution de " + clname
+ ".main() : " + e.getLocalizedMessage());
e.printStackTrace();
setStatus(3);
} catch (IllegalAccessException e) {
LOG.error("Acces interdit a l'execution de " + clname
+ ".main() : " + e.getLocalizedMessage());
setStatus(3);
} catch (InvocationTargetException e) {
setStatus(4);
e.printStackTrace();
}
}
/**
* This method may be used to do something with the
* content of each loaded jar file before they are put into
* the classpath.
*
* @param file the File object representing a jar or zip file.
*/
protected void handleJar(File file) {
// NOP
}
public String[] getArguments() {
return arguments;
}
public void setArguments(String[] arguments) {
this.arguments = arguments;
}
/**
* @return Returns the status.
*/
public int getStatus() {
return status;
}
/**
* @param status The status to set.
*/
public void setStatus(int status) {
this.status = status;
}
/**
* @return Returns the loader.
*/
public URLClassLoader getLoader() {
return loader;
}
/**
* @param loader The loader to set.
*/
public void setLoader(URLClassLoader loader) {
this.loader = loader;
}
}
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Jar With Dependencies
Posted by Arnaud Bailly <ab...@oqube.com>.
Douglas Ferguson <do...@epsiia.com> writes:
> Sure, I'd love to see that script.
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Lanceur implements Runnable {
private static final Log LOG = LogFactory.getLog(Lanceur.class);
/*
* the command line arguments array
*/
private String[] arguments;
/*
* the exit status
*
*/
private int status = 0;
/*
* class loader constructed by this lanceur
*/
private URLClassLoader loader;
public static void main(String[] argv) {
if(argv.length == 0)
System.exit(1);
/* first argument is real lanucher class */
String real = argv[0];
Class realC = Class.forName(real);
/* shift les arguments */
String[] nargs = new String[argv.length - 1];
if (nargs.length != 0) {
System.arraycopy(arguments, 1, nargs, 0, nargs.length);
}
Lanceur l = (Lanceur)realC.newInstance();
l.setArguments(argv);
l.run();
}
public void run() {
/* extraction du repertoire */
String libdir = System.getProperty("libdir","..\\lib");
if (libdir == null) {
LOG.error("Definir le repertoire contenant les bibliotheques : -Dlibdir=<xxxxx>");
setStatus(1);
return;
}
/* verifications */
File f = new File(libdir);
if (!f.exists()) {
LOG.error("Le repertoire" + libdir + " n'existe pas");
setStatus(2);
return;
}
if (!f.isDirectory()) {
LOG.error(libdir + " n'est pas un repertoire");
setStatus(2);
return;
}
if (!f.canRead()) {
LOG.error("Le contenu de " + libdir + " ne peut etre lu");
setStatus(2);
return;
}
/* extraction du nom de la classe principale */
String clname = System.getProperty("main","Main");
if (clname == null)
clname = "Main";
/* construction du classpath */
File[] jars = f.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().endsWith(".jar")
|| pathname.getName().endsWith(".zip");
}
});
int ln = jars.length;
URL[] urls = new URL[ln + 1];
/* ajout du repertoire courant par defaut*/
try {
urls[0] = new URL("file://.");
} catch (MalformedURLException e) {
LOG.error("Impossible d'ajouter . au classpath : "
+ e.getLocalizedMessage());
}
for (int i = 0; i < ln; i++)
try {
handleJar(jars[i]);
urls[i] = new URL("file://" + jars[i].getPath());
} catch (MalformedURLException e) {
LOG.error("Impossible d'ajouter . au classpath : "
+ e.getLocalizedMessage());
}
/* chargement */
loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
try {
Class cls = loader.loadClass(clname);
Method main = cls.getDeclaredMethod("main", new Class[] { nargs
.getClass() });
LOG.debug("Execution de "+clname +".main(");
for(int i=0;i<arguments.length;i++) {
LOG.debug(arguments[i]);
if(i < arguments.length -1)
LOG.debug(','+"");
}
LOG.debug(")");
main.invoke(null, new Object[] { nargs });
} catch (ClassNotFoundException e) {
LOG.error("Impossible de trouver la classe " + clname
+ " : " + e.getLocalizedMessage());
setStatus(3);
} catch (SecurityException e) {
LOG.error("Erreur de securite pour charger la methode main dans "
+ clname + " : " + e.getLocalizedMessage());
setStatus(3);
} catch (NoSuchMethodException e) {
LOG.error("Impossible de trouver la methode main dans "
+ clname + " : " + e.getLocalizedMessage());
setStatus(3);
} catch (IllegalArgumentException e) {
LOG.error("Argument incorrecte a l'execution de " + clname
+ ".main() : " + e.getLocalizedMessage());
e.printStackTrace();
setStatus(3);
} catch (IllegalAccessException e) {
LOG.error("Acces interdit a l'execution de " + clname
+ ".main() : " + e.getLocalizedMessage());
setStatus(3);
} catch (InvocationTargetException e) {
setStatus(4);
e.printStackTrace();
}
}
/**
* This method may be used to do something with the
* content of each loaded jar file before they are put into
* the classpath.
*
* @param file the File object representing a jar or zip file.
*/
protected void handleJar(File file) {
// NOP
}
public String[] getArguments() {
return arguments;
}
public void setArguments(String[] arguments) {
this.arguments = arguments;
}
/**
* @return Returns the status.
*/
public int getStatus() {
return status;
}
/**
* @param status The status to set.
*/
public void setStatus(int status) {
this.status = status;
}
/**
* @return Returns the loader.
*/
public URLClassLoader getLoader() {
return loader;
}
/**
* @param loader The loader to set.
*/
public void setLoader(URLClassLoader loader) {
this.loader = loader;
}
}
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Jar With Dependencies
Posted by Arnaud Bailly <ab...@oqube.com>.
Douglas Ferguson <do...@epsiia.com> writes:
> Sure, I'd love to see that script.
Just to be clear, this is not a script, this is java code for a
wrapper main application that just adds all jars it find in a list of directories
in a classloader then call the real main. I used this as a stable main
entry point for an application assembled with maven-assembly-plugin
which had a set of changing components and as a replacement for a
platform-dependent script.
For loading jars inside jar:
http://www-128.ibm.com/developerworks/library/j-onejar/
The main wrapper is sent to you by mail.
regards.
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
RE: Jar With Dependencies
Posted by Douglas Ferguson <do...@epsiia.com>.
Sure, I'd love to see that script.
----- Original Message -----
From: Arnaud Bailly
Sent: Wed, 8/23/2006 2:01am
To: Maven Users List
Subject: Re: Jar With Dependencies
Douglas Ferguson <do...@epsiia.com> writes:
> Does anybody have a suggestion for creating a jar with dependencies
> that has all the dependencies exploded?
There is an <unpack> tag in assembly descriptor that does this.
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
>
> If I send them a jar with dependencies, then they would have to crack
> the jar open, because the classloader won't read a jar within a jar.
>
I think that classworlds can do this. You could also write a simple
wrapper classloader that launches your application. I did this once to
ensure platform-independent classpath resolution as I could not write
a script in windows that would add a list of jars in one lib to
classpath (not an expert rin windows scripting obviously).
If you are interested by this small snippet, I can send you.
BTW, IBM released recently a tool for doing just that kind of things
(loading jars from jars). Lost references to it.
regards
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Jar With Dependencies
Posted by Arnaud Bailly <ab...@oqube.com>.
Douglas Ferguson <do...@epsiia.com> writes:
> Does anybody have a suggestion for creating a jar with dependencies
> that has all the dependencies exploded?
There is an <unpack> tag in assembly descriptor that does this.
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
>
> If I send them a jar with dependencies, then they would have to crack
> the jar open, because the classloader won't read a jar within a jar.
>
I think that classworlds can do this. You could also write a simple
wrapper classloader that launches your application. I did this once to
ensure platform-independent classpath resolution as I could not write
a script in windows that would add a list of jars in one lib to
classpath (not an expert rin windows scripting obviously).
If you are interested by this small snippet, I can send you.
BTW, IBM released recently a tool for doing just that kind of things
(loading jars from jars). Lost references to it.
regards
--
OQube < software engineering \ génie logiciel >
Arnaud Bailly, Dr.
\web> http://www.oqube.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org