2016-09-05 3 views
1

3週間後、私はJarClassLoaderとreflexionを使って書いたプラグインをロードしようとしています。
プラグインの読み込みは完璧ですが、私は永続性とエンティティクラスを使用する必要があるとき、私はこのエラーを取得:プラグインの永続性を使用して、Javaでreflexionを使用してロードする

GRAVE: null 
java.lang.reflect.InvocationTargetException 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.amepa.plugin03.Test.main(Test.java:29) 
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named pu 
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:85) 
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54) 
at plugin.Main.getLocalFactory(Main.java:126) 
... 5 more 

私はjava -jar plugin.jar を使用してコマンドラインでプラグインを実行すると、それは完全に私に私からフェッチされたデータを示す実行しますデータベース。 また、私は持続性APIを使用せず、ドライバを介して直接接続すると、私は正しい結果を得ます。

私はエラーがどこから来たのか、可能であればそれを解決する方法を理解したいと思います。

これはプラグインのコードです:

public class Main /*implements PluginImplement*/{ 

    public List<String> getStudent(){ 
     List<Eleves> findElevesEntities = (new ElevesJpaController(getLocalFactory())).findElevesEntities(); 
     List<String> lst = new ArrayList<>(); 
     for(Eleves el : findElevesEntities){ 
      lst.add(el.toString()); 
      System.out.println(" Eleves : "+el.toString()); 
     } 
     return lst; 
    } 

    public static void main(String args[]){ 
     Main m = new Main(); 
     m.getStudent(); 
    } 

    public static EntityManagerFactory getLocalFactory() { 
     return Persistence.createEntityManagerFactory("pu"); 
    } 
} 

これは私の永続ファイルです:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns /persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
<class>entities.Eleves</class> 
<properties> 
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/emt?zeroDateTimeBehavior=convertToNull"/> 
    <property name="javax.persistence.jdbc.user" value="user"/> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
    <property name="javax.persistence.jdbc.password" value="password"/> 
</properties> 
    </persistence-unit> 
</persistence> 

エンティティ

@Entity 
@Table(name = "eleves") 
@XmlRootElement 
public class Eleves implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 
    @Column(name = "created") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date created; 
    @Column(name = "date_bapteme") 
    @Temporal(TemporalType.DATE) 
    private Date dateBapteme; 
    @Column(name = "date_inscription_ecole") 
    @Temporal(TemporalType.DATE) 
    private Date dateInscriptionEcole; 
    @Column(name = "date_naissance") 
    @Temporal(TemporalType.DATE) 
    private Date dateNaissance; 
    @Column(name = "email") 
    private String email; 
    @Basic(optional = false) 
    @Column(name = "nom") 
    private String nom; 
    @Basic(optional = false) 
    @Column(name = "prenom") 
    private String prenom; 
    @Column(name = "numero") 
    private String numero; 

    public Eleves() { 
    } 

    public Eleves(Integer id) { 
     this.id = id; 
    } 

    public Eleves(Integer id, String nom, String prenom) { 
     this.id = id; 
     this.nom = nom; 
     this.prenom = prenom; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public Date getCreated() { 
     return created; 
    } 

    public void setCreated(Date created) { 
     this.created = created; 
    } 

    public Date getDateBapteme() { 
     return dateBapteme; 
    } 

    public void setDateBapteme(Date dateBapteme) { 
     this.dateBapteme = dateBapteme; 
    } 

    public Date getDateInscriptionEcole() { 
     return dateInscriptionEcole; 
    } 

    public void setDateInscriptionEcole(Date dateInscriptionEcole) { 
     this.dateInscriptionEcole = dateInscriptionEcole; 
    } 

    public Date getDateNaissance() { 
     return dateNaissance; 
    } 

    public void setDateNaissance(Date dateNaissance) { 
     this.dateNaissance = dateNaissance; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public String getNom() { 
     return nom; 
    } 

    public void setNom(String nom) { 
     this.nom = nom; 
    } 

    public String getPrenom() { 
     return prenom; 
    } 

    public void setPrenom(String prenom) { 
     this.prenom = prenom; 
    } 

    public String getNumero() { 
     return numero; 
    } 

    public void setNumero(String numero) { 
     this.numero = numero; 
    } 

    @Override 
    public String toString() { 
     return "Eleves{" + "id=" + id + ", created=" + created + ", dateBapteme=" + dateBapteme + ", dateInscriptionEcole=" + dateInscriptionEcole + ", dateNaissance=" + dateNaissance + ", email=" + email + ", nom=" + nom + ", prenom=" + prenom + ", numero=" + numero + '}'; 
    } 
} 

とコントローラ:

public class ElevesJpaController implements Serializable { 

    public ElevesJpaController(EntityManagerFactory emf) { 
     this.emf = emf; 
    } 
    private EntityManagerFactory emf = null; 

    public EntityManager getEntityManager() { 
     return emf.createEntityManager(); 
    } 


    public List<Eleves> findElevesEntities() { 
     return findElevesEntities(true, -1, -1); 
    } 

    public List<Eleves> findElevesEntities(int maxResults, int firstResult) { 
     return findElevesEntities(false, maxResults, firstResult); 
    } 

    private List<Eleves> findElevesEntities(boolean all, int maxResults, int firstResult) { 
     EntityManager em = getEntityManager(); 
     try { 
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); 
      cq.select(cq.from(Eleves.class)); 
      Query q = em.createQuery(cq); 
      if (!all) { 
       q.setMaxResults(maxResults); 
       q.setFirstResult(firstResult); 
      } 
      return q.getResultList(); 
     } finally { 
      em.close(); 
     } 
    } 

    public Eleves findEleves(Integer id) { 
     EntityManager em = getEntityManager(); 
     try { 
      return em.find(Eleves.class, id); 
     } finally { 
      em.close(); 
     } 
    } 

    public int getElevesCount() { 
     EntityManager em = getEntityManager(); 
     try { 
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); 
      Root<Eleves> rt = cq.from(Eleves.class); 
      cq.select(em.getCriteriaBuilder().count(rt)); 
      Query q = em.createQuery(cq); 
      return ((Long) q.getSingleResult()).intValue(); 
     } finally { 
      em.close(); 
     } 
    }  
} 

これらはすべてmavenを使用してjarファイルにパッケージ化されています。

jarファイルをロードする主要なクラスがある:私は上記のリンクでのコードの私の修正版を追加 http://kalanir.blogspot.com/2010/01/how-to-write-custom-class-loader-to.html

public class Test { 
    public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException{ 
     JarClassLoader jcl = new JarClassLoader(); 
     Class loadClass = jcl.loadClass("plugin.Main"); 
     System.out.println(" Class : "+loadClass); 
     for(Method m : loadClass.getDeclaredMethods()) 
      System.out.println(" Method : "+m.getName()); 

     Method declaredMethod = loadClass.getDeclaredMethod("getStudent"); 
     try { 
      Object newInstance = loadClass.newInstance(); 
      declaredMethod.invoke(newInstance); 
     } catch (IllegalAccessException ex) { 
      Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IllegalArgumentException ex) { 
      Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (InvocationTargetException ex) { 
      Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

JarClassLoaderはこのポストから派生したクラスであります

public class JarClassLoader extends ClassLoader { 
private final String jarFile = "path_to_jar.jar"; //Path to the jar file 
private Hashtable classes = new Hashtable(); //used to cache already defined classes 
public JarClassLoader() { 
    super(JarClassLoader.class.getClassLoader()); //calls the parent class loader's constructor 
} 
public Class loadClass(String className) throws ClassNotFoundException { 
    return findClass(className); 
} 
public Class findClass(String className) { 
    byte classByte[]; 
    Class result = null; 

    result = (Class) classes.get(className); //checks in cached classes 
    if (result != null) { 
     return result; 
    } 

    try { 
     return findSystemClass(className); 
    } catch (Exception e) { 

    } 

    try { 
      className = className.replaceAll("\\.", "/"); 
     JarFile jar = new JarFile(jarFile); 
     Enumeration<JarEntry> entries = jar.entries(); 
     JarEntry entry = jar.getJarEntry(className + ".class"); 
     InputStream is = jar.getInputStream(entry); 
     ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 
     int nextValue = is.read(); 
     while (-1 != nextValue) { 
      byteStream.write(nextValue); 
      nextValue = is.read(); 
     } 

      classByte = byteStream.toByteArray(); 
    className = className.replaceAll("/","\\."); 
result = defineClass(className, classByte, 0, classByte.length,null); 
     classes.put(className, result); 
     return result; 
    } catch (Exception e) 
    { e.printStackTrace(); 
     return null; 
    } 
} 

} 

ありがとうございます。

+0

JarClassLoaderをそのままポストから派生させてください。 –

+0

あなたのクラスパス参照を共有できますか? – user1224036

+0

なぜ 'URLClassLoader'を使わなかったのですか? – talex

答えて

0

あなたのリンクにコードから派生したJarClassLoaderを使用すると、記述が悪く、バグがあります。

URLClassLoaderを使用してください。

+0

私は既にクラスを使用しようとしましたが、同じエラーが発生します。 Persistence.createEntityManagerFactory( "pu")の呼び出しがない限り、コードは正しく実行されます。私はこの問題がJPAの読み込み方法に関連していると思います。 – amepa

関連する問題