Jar-Archiv mit benötigten libraries erstellen

mas666

Mitglied
Hallo zusammen

Ich möchte ein jar erstellen das verschiedene andere jars die es benötigt (hibernate, log4j, und weitere) enthält. Wenn ich mit Eclipse ein jar erstelle, das ein einfaches Hello-World-Beispiel enthält, geht das.

Dies ist die Java-Datei
Java:
public class MainClass {

	public static void main(String[] args) {
		System.out.println("Hello World");
	}

}

Manifest:
Code:
Manifest-Version: 1.0
Sealed: true
Main-Class: ch.arocom.test.MainClass

Aufruf:
Code:
java -jar test.jar

Wenn ich nun die Funktionen einer externen library in Anspruch nehme (folgendes Beispiel: javax.mail) und dann wiederum mit Eclipse ein jar erstelle, kriege ich folgendes Problem. (Das Mail-Beispiel funktioniert aus Eclipse).

Java:
public class MainClass {
	    
	public void sendMail(String smtpHost,String username,String password,String senderAddress,String recipientsAddress,String subject,String text ){
		MailAuthenticator auth = new MailAuthenticator(username, password);
	 
		Properties properties = new Properties();
		properties.put("mail.smtp.host", smtpHost);
		properties.put("mail.smtp.auth", "true");
		properties.put("mail.smtp.port", "587");
		properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
		Session session = Session.getDefaultInstance(properties, auth);
	 
		try {
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress(senderAddress));
			msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientsAddress, false));
			msg.setSubject(subject);
			msg.setText(text);
			msg.setHeader("Test", "Test");
			msg.setSentDate(new Date( ));
			Transport.send(msg);
		}
		catch (Exception e) {
			e.printStackTrace( );
		}
	}
	    
	class MailAuthenticator extends Authenticator {
	 
		private final String user;
		private final String password;
	 
		public MailAuthenticator(String user, String password) {
			this.user = user;
			this.password = password;
		}
	 
		protected PasswordAuthentication getPasswordAuthentication() {
			return new PasswordAuthentication(this.user, this.password);
		}
	}
	    
	public static void main(String[] args) {
	 
	        String username = "xxxxx.yyyyy";
	        String password = "*******";
	        String senderAddress ="xxxxx.yyyyy@gmail.com";
	        String recipientsAddress = "test@web.de";
	        String subject = "Test";
	        String text = "text";
	        String smtpHost = "smtp.gmail.com";
	        
	        new MainClass().sendMail(smtpHost, username, password, senderAddress, recipientsAddress, subject, text);
	    }
	}

Ich rufe das jar aus der Kommandozeile folgendermassen auf:
Code:
java -jar test.jar

Dann wird folgender Fehler ausgegeben:
Code:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Authenticator
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.getMainMethod(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.mail.Authenticator
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 6 more

Daraufhin habe ich das MANIFEST geändert. Alt:
Code:
Manifest-Version: 1.0
Sealed: true
Main-Class: ch.arocom.test.MainClass

Neu:
Code:
Manifest-Version: 1.0
Sealed: true
Class-Path: lib/mail.jar
Main-Class: ch.arocom.test.MainClass

Der Fehler bleibt derselbe. Die Struktur innerhalb des jars ist folgende:

Code:
META-INF
 |-MANIFEST.mf
lib
 |-mail.jar
ch
 |-arocom
    |-test
      |-MainClass.class
      |-MainClass$MailAuthenticator.class
.project
.classpath

Was mache ich falsch? Wie kann ich die library (und in Zukunft mehrere weitere) einbinden oder wie gehe ich in diesem Fall vor?

Was ich am Schluss erreichen möchte ist das JAR als Windows-Service laufen zu lassen. Dies funktioniert dank dem commons daemon von apache (http://commons.apache.org/proper/commons-daemon/) gut, so lange ich keine externen jars in meinem exportierten JAR habe...

Danke für jede Hilfe und jeden Tipp!

Gruss
soma
 

diel2001

Mitglied
Eclipse bietet dir doch eine Export-funktion und er kopiert alle benötigten Libraries mit,
wenn du eine RunnableJar erstellst.
 

diel2001

Mitglied
Eclipse bietet dir doch eine Export-funktion und er kopiert alle benötigten Libraries mit,
wenn du eine RunnableJar erstellst.

Code:
java -cp (lib.test.jar;...) -jar test.jar

So müßte es funktionieren
 

youza

Erfahrenes Mitglied
Konsole sieht bei mir ungefähr so aus:

Kompelieren(vom src folder aus):
Code:
javac -cp .:classes:/lib/'*' -d . com/youza/logic/test.jar

ausführen:
Code:
java -cp .:classes:/lib/'*' com/youza/logic/test.jar

der lib Ordner enthält alle benötigten libaries.

von Eclipse aus wie diel2001 schon sagt eine runnableJar bauen. Funktioniert beides des mit der Konsole hab ich auch erst rausgefunden nachdem ich mal auf Eclipse verzichten musste (Raspberry Pi) :D

Grüße
Youza
 

mas666

Mitglied
Hallo diel2001, Hallo Youza

Danke für eure Antworten. Der Eclipse-Export als Runnable-jar hat irgendwie nicht funktioniert, ich muss mir das noch näher anschauen.

Ich habe jetzt mein JAR in einem Verzeichnis mit dem Ordner lib und habe den Class-Path mit meinen externen libraries im MANIFEST angegeben:

Code:
Manifest-Version: 1.0
Sealed: true
Class-Path: lib/antlr-2.7.6.jar lib/commons-collections-3.2.1.jar lib/commons-logging-1.1.1.jar lib/dom4j-1.6.1.jar lib/hibernate3.jar lib/hibernate-annotations.jar lib/hibernate-commons-annotations.jar lib/hibernate-entitymanager.jar lib/javaee-api-6.0-3.jar lib/javassist-3.15.0-GA.jar lib/log4j-1.2.17.jar lib/mysql-connector-java-5.1.20-bin.jar lib/slf4j-api-1.6.6.jar lib/slf4j-jcl-1.6.6.jar 
Main-Class: ch.arocom.uhr.service.NetLinxServer

Beste Grüsse
soma
 

Neue Beiträge