2013-11-03 6 views
10

में चलते समय कोई त्रुटि नहीं है। मैं जावा ऐप्स बनाने के लिए शुरू कर रहा हूं (मेरे पास .NET अनुभव है) और मैं एक छोटा परीक्षण ऐप बनाने की कोशिश कर रहा था जिसका पूरा कोड यह है:JAR चलाने पर ClassNotFoundException, IntelliJ IDEA

package com.company; 

import com.microsoft.sqlserver.jdbc.SQLServerDataSource; 

import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

public class Main { 

    public static void main(String[] args) throws SQLException { 
     System.out.println("Buna lume!"); 

     SQLServerDataSource ds = new SQLServerDataSource(); 
     ds.setIntegratedSecurity(true); 
     ds.setServerName("localhost"); 
     ds.setPortNumber(1433); 
     ds.setDatabaseName("Test"); 
     Connection con = ds.getConnection(); 

     String SQL = "SELECT * FROM Test WHERE ID = ?"; 
     PreparedStatement stmt = con.prepareStatement(SQL); 
     stmt.setInt(1, 2); 
     ResultSet rs = stmt.executeQuery(); 

     while (rs.next()) { 
      System.out.println(rs.getInt(1) + ", " + rs.getString(2)); 
     } 
     rs.close(); 
     stmt.close(); 

     con.close(); 
    } 
} 

यदि मैं आईडीई (इंटेलिजे आईडीईए 12.1.6 सामुदायिक संस्करण) में ऐप चलाता हूं, जिसमें SQL सर्वर उपलब्ध है, तो ऐप ठीक से चल रहा है जो इसे करना चाहिए।

SQL सर्वर ड्राइवर Microsoft से डाउनलोड किया गया है और एक बाहरी पुस्तकालय के रूप में जोड़ा गया है। मैं JAR फ़ाइल के रूप में एक विरूपण साक्ष्य बनाया है:

enter image description here

अब, अगर मैं cliTest.jar (मेरे जार) के परिणामस्वरूप JAR मोटा है (550kB में sqljdbc4.jar शामिल हैं और कि जार में वर्ग शामिल भी)। या मैं इसे बाहर कर सकते हैं। किसी भी तरह से,

Buna lume! 
Exception in thread "main" java.lang.NoClassDefFoundError: com/microsoft/sqlserv 
er/jdbc/SQLServerDataSource 
     at com.company.Main.main(Main.java:15) 
Caused by: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLSer 
verDataSource 
     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) 
     ... 1 more 

में चल

java -jar cliTest.jar 

परिणाम मुझे यकीन है कि मैं कुछ काफी बुनियादी याद कर रहा हूँ, लेकिन मैं सिर्फ वास्तव में क्या यह हो रही है, नहीं कर सकते।

LE1: मैंने jq युक्त निर्देशिका में sqljdbc4.jar (हालांकि यह आवश्यक प्रतीत नहीं हुआ) और sqljdbc_auth.dll जोड़ने का प्रयास किया लेकिन अभी भी कोई बदलाव नहीं है।

बाद में संपादित करें 2: निकोले के जवाब के आधार पर मेरे द्वारा की गई है:

enter image description here

:

  1. मौजूदा विरूपण साक्ष्य
  2. बनाया गया तो जैसे एक नया विरूपण साक्ष्य नष्ट कर दिया गया enter image description here

    .. ए nd हुई इस:

    enter image description here

    1. बिल्ड -> बिल्ड कलाकृतियों -> cliTest.jar -> पुनर्निर्माण

    2. वाले फ़ोल्डर में

      सीएमडी आदेश:

    [cliTest.jar 566 KB जनरेट किया गया था]

    जावा जार cliTest.jar

    अब मैं मिलता है:

    Exception in thread "main" java.lang.SecurityException: Invalid signature file d 
    igest for Manifest main attributes 
        at sun.security.util.SignatureFileVerifier.processImpl(Unknown Source) 
        at sun.security.util.SignatureFileVerifier.process(Unknown Source) 
        at java.util.jar.JarVerifier.processEntry(Unknown Source) 
        at java.util.jar.JarVerifier.update(Unknown Source) 
        at java.util.jar.JarFile.initializeVerifier(Unknown Source) 
        at java.util.jar.JarFile.getInputStream(Unknown Source) 
        at sun.misc.URLClassPath$JarLoader$2.getInputStream(Unknown Source) 
        at sun.misc.Resource.cachedInputStream(Unknown Source) 
        at sun.misc.Resource.getByteBuffer(Unknown Source) 
        at java.net.URLClassLoader.defineClass(Unknown Source) 
        at java.net.URLClassLoader.access$100(Unknown Source) 
        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) 
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source) 
    

उत्तर

3

वैसे मुझे sqljdbc4.jar एम्बेडेड के बिना जार बनाया जाना चाहिए था।

दूसरी बात मैं बहुत की तरह आदेश चला जाना चाहिए था:

java -classpath sqljdbc4.jar;cliTest.jar com.company.Main 

.. और फिर सभी काम किया!

+0

यह एक तरीका है। लेकिन एक ही जार में प्रत्येक वर्ग फ़ाइल को एम्बेड करना भी काम करना चाहिए। ध्यान दें कि जार फ़ाइलें वास्तव में ज़िप फ़ाइलें हैं, इसलिए आप उन्हें हमेशा खोल सकते हैं और यह देखने के लिए अंदर देख सकते हैं कि उनमें सभी कक्षाएं हैं या नहीं। – lbalazscs

+0

हां, मैंने आश्रित जेएआर (sqljdbc4.jar) में देखा है, लेकिन इसके परिणामस्वरूप इसे उत्पन्न करने की कोशिश कर रहा है JAR प्रश्न के अंतिम भाग में सुरक्षा अपवाद उत्पन्न करेगा। मुझे लगता है कि जेएआर को एम्बेड किया जा रहा था पर हस्ताक्षर किए गए थे और इसमें शामिल नहीं था ... या ऐसा कुछ। –

+0

हां, यदि आप एक बड़े जार में हस्ताक्षरित जार की सभी फाइलें एम्बेड करते हैं, तो हस्ताक्षर समस्याएं पैदा कर सकता है। आप हस्ताक्षर से छुटकारा पाने के लिए मेटा-आईएनएफ/* एसएफ, मेटा-आईएनएफ/* डीएसए और मेटा-आईएनएफ/* आरएसए फाइलों को हटा सकते हैं। – lbalazscs

4

उपयोग java -cpjava -jar के बजाय और आप सभी classpath को जार निर्भरता डाल दिया।

एक और तरीका सभी निर्भरताओं को सिंगल जार में पैक कर रहा है, जो आपको java -jar का उपयोग करके एप्लिकेशन चलाने की इजाजत देता है।

संपादित करें:

जावा में * .jar फ़ाइल वर्गों में से एक थोक में शामिल है। जब आप अपना ऐप बनाते हैं, आम तौर पर, परिणाम जार फ़ाइल में केवल आपकी कक्षाएं होती हैं, लेकिन फिर भी आपके द्वारा उपयोग की जाने वाली बाहरी पुस्तकालयों (तथाकथित निर्भरताओं) से कक्षाएं लोड करनी होंगी।

  1. आप अपने आवेदन के लिए एक फ़ोल्डर बनाने, उदाहरण के लिए, lib कहा जाता है और आपके आवेदन जार और में सभी निर्भरता जगह:

    यह दो अलग अलग तरीकों से किया जा सकता। तो फिर तुम java -cp lib:/\* com.company.Main या का उपयोग कर अनुप्रयोग चलाने (धन्यवाद @NilsH, मैं इस प्रकार की याद आती है) आप MANIFEST.MF फ़ाइल बनाने के लिए और Main-Class निर्दिष्ट और Classpath के रूप में अंदर विशेषताओं का वर्णन किया here

  2. यदि आप का उपयोग की तरह Maven-निर्भरता-प्लगइन (विशेष उपकरण का उपयोग निर्माण के लिए मेवेन) सभी वर्गों को पैक करने के लिए, या तो स्वयं, एकल यार के बाहर बाहरी। आपको एक बड़ी फ़ाइल मिली है और इसे java -jar cliTest.jar का उपयोग करके चलाया जा सकता है।

आम तौर पर, पहले दृष्टिकोण पसंद किया जाता है और एक MANIFEST.MF फ़ाइल का उपयोग कर एक अच्छा तरीका है।

+0

ठीक है, लेकिन मैं अभी भी जार का निर्माण करता हूं या नहीं? –

+0

हां, मैंने अपना जवाब समझाया है। – Nikolay

+0

मुझे असहमत होना है। निष्पादन योग्य जार बनाने का "उचित" तरीका जार फ़ाइल के मेटा-आईएनएफ फ़ोल्डर में उचित MANIFEST.MF फ़ाइल होना है और इसे 'जावा -जर' के साथ चलाएं। 'MANIFEST.MF' फ़ाइल में मेनिफेस्ट की' मुख्य-श्रेणी 'विशेषता के अलावा,' क्लास-पथ 'अनुभाग में निर्भर जार के लिए प्रविष्टियां होनी चाहिए। – NilsH

-1

ठीक है अगर आप मेवेन का उपयोग कर रहे हैं तो आप आवेदक जार में निष्पादित जार को शामिल करने के लिए मेवेन-शेड-प्लगइन का उपयोग कर सकते हैं, pom.xml का स्निपेट नीचे दिया गया है।

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-shade-plugin</artifactId> 
       <version>2.4.3</version> 
       <executions> 
        <execution> 
         <phase>package</phase> 
         <goals> 
          <goal>shade</goal> 
         </goals> 
         <configuration> 
          <transformers> 
           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">          <mainClass>com.main.class.YouMainClass</mainClass> 
           </transformer> 
          </transformers> 
          <filters> 
           <filter> 
            <artifact>*:*</artifact> 
            <excludes> 
             <exclude>META-INF/*.SF</exclude> 
             <exclude>META-INF/*.DSA</exclude> 
             <exclude>META-INF/*.RSA</exclude> 
            </excludes> 
           </filter> 
          </filters> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin>