0

I am working on the integration of two developed swing applications (host and guest). The guest application is included as a jar file in the host project. For communication between them, I created an interface inside the guest and implemented it inside the host.

// inside host 
GUEST guest= GUEST.getInstance( );
Socket2host socket = new Socket2host() {
               .
               .
               . 
                };
guest.setSocket(socket);

Everything works well. However, after release, I noticed that the guest cannot load a class from its own source. Indeed, the guest application tries to reload a project using a Serializer from an xml file(the developer used simpleframework library for this). Here you can look inside the code:

Serializer serializer = new Persister();
setInstanceFromXML(serializer, *xml string);


    public static void setInstanceFromXML(Serializer s, String in){
        try {
            s.read(SingletonHolder.instance, in);
        } catch (Exception ex) {
            // Logging
        }
    }

When I run the project in Eclipse, it works well and I can see the desired class in the current thread. but when I run the release version, the following error is logged on the console.

java.lang.ClassNotFoundException: ipad.experimentSettings.IPADExperimental1DSVSSettings
        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 org.simpleframework.xml.strategy.TreeStrategy.getClass(TreeStrategy.java:270)
        at org.simpleframework.xml.strategy.TreeStrategy.getValue(TreeStrategy.java:183)
        at org.simpleframework.xml.strategy.TreeStrategy.getElement(TreeStrategy.java:123)
        at org.simpleframework.xml.core.Source.getOverride(Source.java:330)
        at org.simpleframework.xml.core.Factory.getConversion(Factory.java:144)
        at org.simpleframework.xml.core.Factory.getOverride(Factory.java:100)
        at org.simpleframework.xml.core.ObjectFactory.getInstance(ObjectFactory.java:64)
        at org.simpleframework.xml.core.Composite.read(Composite.java:125)
        at org.simpleframework.xml.core.Composite.readObject(Composite.java:621)
        at org.simpleframework.xml.core.Composite.read(Composite.java:567)
        at org.simpleframework.xml.core.Composite.readElement(Composite.java:548)
        at org.simpleframework.xml.core.Composite.readElements(Composite.java:464)
        at org.simpleframework.xml.core.Composite.read(Composite.java:350)
        at org.simpleframework.xml.core.Composite.read(Composite.java:158)
        at org.simpleframework.xml.core.Traverser.read(Traverser.java:106)
        at org.simpleframework.xml.core.Persister.read(Persister.java:707)
        at org.simpleframework.xml.core.Persister.read(Persister.java:687)
        at org.simpleframework.xml.core.Persister.read(Persister.java:667)
        at org.simpleframework.xml.core.Persister.read(Persister.java:648)
        at org.simpleframework.xml.core.Persister.read(Persister.java:565)
        at ipad.IPADConditions.setInstanceFromXML(IPADConditions.java:89)
        at ipad.IPADApp.reloadFitProject(IPADApp.java:2974)
        at ipad.IPADApp.loadFitProject(IPADApp.java:2901)
        at ipad.ui.IPADMenuBar.actionPerformed(IPADMenuBar.java:257)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
        at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
        at javax.swing.AbstractButton.doClick(Unknown Source)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
        at java.awt.Component.processMouseEvent(Unknown Source)
        at javax.swing.JComponent.processMouseEvent(Unknown Source)
        at java.awt.Component.processEvent(Unknown Source)
        at java.awt.Container.processEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Window.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$500(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

here is the snippet of xml file:(ipad.experimentSettings.IPADExperimental1DSVSSettings is desired class)

<experimentalParameterSettings class="ipad.experimentSettings.IPADExperimental1DSVSSettings">
      <numberOfResponses>1</numberOfResponses>
      <TEsDefined>true</TEsDefined>
      <TRsDefined>false</TRsDefined>
      <TSsDefined>false</TSsDefined>
      <TIsDefined>false</TIsDefined>
      <TMsDefined>false</TMsDefined>
      <TOthersDefined>false</TOthersDefined>
      <TEs length="1">
         <double>0.0</double>
      </TEs>
      <TRs length="1">
         <double>0.0</double>
      </TRs>
      <TSs length="1">
         <double>30.0</double>
      </TSs>
      <TIs length="1">
         <double>0.0</double>
      </TIs>
      <TMs length="1">
         <double>0.0</double>
      </TMs>
      <TOthers length="1">
         <double>0.0</double>
      </TOthers>
      <currentExperimentType>SVS_1D</currentExperimentType>
   </experimentalParameterSettings>

I already added the guest application(as a JAR file) to the classpath, So this post didn't help me. I defined the classpath as what I had on eclipse but it did not work. I checked the "current thread", but the app could not find the desired class. Here you can find a minimal reproducible example of loading the guest's class.

// host app
import java.awt.event.*;  
import javax.swing.*;    
public class ButtonExample {  
public static void main(String[] args) {  
    JFrame f=new JFrame("minimal reproducible example");  
    final JTextField tf=new JTextField();  
    tf.setBounds(50,50, 150,20);  
    JButton b=new JButton("Click Here");  
    b.addActionListener(new ActionListener(){  
        public void actionPerformed(ActionEvent e){  
            Guest guest = Guest.getInstance;  
        }  
    });  
    f.setLayout(null);  
    f.setVisible(true);   
}  
}  

// guest app
public class Guest extends JFrame implements ActionListener {
private static Guest theInstance = null;
public Guest (){
String in = <address to desired class in the package> 
try {   
 System.out.println(Thread.currentThread().getContextClassLoader().loadClass(in));
} catch (Exception ex) {
    System.out.println(ex);
}
}

public static Guest getInstance( )
{
    if ( theInstance == null )
    {
        theInstance = new Guest ( );
    }

    return theInstance;
}


// desired class for loading
public class DesiredClass{
    public DesiredClass() {
    }
}

Additional info: the below code runs the released version.

set javaFile="C:\Program Files (x86)\Java\jre1.8.0_202\bin\java"
cd /d %~dp0
set path=%path%;%CD%\lib
%javaFile% -Xss2m -Xmx900m -Djava.library.path=lib -jar lib/mrui.jar %*
pause

I was wondering why the classes of the guest appear in Eclipse but it cannot be loaded in the released version.

  • There is not enough information here to know what is going wrong. So some questions: 1) *"while running a Swing App as a jar file **inside** another Awing App"* By 'inside' DYM that one Jar is put inside another one, or that Jar is added to the run-time class path of the the main application? 2) Anything in a Jar is an embedded-resource which must be accessed by URL. Is the code doing that? 3) Does the code `catch` any exceptions for which it does *not* print a stack trace? **General Tip:** 1) For better help sooner, [edit] to add a [MCVE]. 2) You seem to be new (to SO, if not programming) .. – Andrew Thompson Jul 30 '21 at 20:58
  • .. but this task is hardly a 'newbie level' of programming. If I understand correctly (which I may not), the code has to first load the XML file (an embedded resource), then use an API to parse that file, then dynamically load classes. None of that is 'Java 101'. Perhaps you should first focus on getting simpler apps working. – Andrew Thompson Jul 30 '21 at 21:01

0 Answers0