Mirth Connect
  1. Mirth Connect
  2. MIRTH-3991

Saving mirth.properties while Server Manager is open can cause corruption

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.3, 3.1.1, 3.2.2, 3.3.2, 3.4.1
    • Fix Version/s: 3.5.0, 3.4.2
    • Component/s: Server, Server Manager
    • Labels:
      None

      Description

      • Open the Server Manager.
      • While the manager is still open, open up mirth.properties in an editor and save it.
      • Go back to the manager, make some change, and hit Apply.

      These steps will usually cause mirth.properties to wig out. In particular, the protocol / cipher suite entries will for some reason decouple into multiple lines, causing HTTPS traffic between the client and server to fail.

      As a workaround, just make sure to close (do not hit OK or Apply) the server manager and tray icon and reopen it whenever you want to make any changes using it.

      1. mirth.corrupted.properties
        6 kB
        Minh Tran
      1. error.png
        53 kB
      2. newPrompt.png
        126 kB

        Activity

        Hide
        Nick Rupley added a comment -

        Fixed in revisions 8068/8069. Now whenever saving properties, the manager will first check whether they have changed, and prompt the user to overwrite first. If the user accepts, the manager will first reload the layout before saving anything new.

        Migrate3_4_0 was previously always saving the properties even if nothing changed. Now we only do that if "sqlserver2000" appears in the comment.

        The configuration controller will now use getStringArray to read the protocol / cipher suite properties, just in case they have decoupled for whatever reason.

        Show
        Nick Rupley added a comment - Fixed in revisions 8068/8069. Now whenever saving properties, the manager will first check whether they have changed, and prompt the user to overwrite first. If the user accepts, the manager will first reload the layout before saving anything new. Migrate3_4_0 was previously always saving the properties even if nothing changed. Now we only do that if "sqlserver2000" appears in the comment. The configuration controller will now use getStringArray to read the protocol / cipher suite properties, just in case they have decoupled for whatever reason.
        Hide
        Minh Tran added a comment - - edited

        OS(s) and JRE version: virtual Window 7 with JRE version 1.8.0_91-b14
        Version(s)/Build(s) to reproduce failure: mirthconnect-3.4.1.8057.b139-windows-x64
        Version(s)/Build(s) to verify fixes: mirthconnect-3.5.0.8075.b1998-windows-x64.exe
        How Tested:

        1. Launch & Open Mirth Connect Server Manager
        2. From Window Explorer, go to <mirth install>/conf/, make a copy of mirth.properties (save as .original)
        3. Open mirth.properties in editor, make some comments, save changes and exit editor
        4. Back to Server Manager, make changes to Server > Log Level > select Apply
        5. Verify content of the current mirth.properties vs. the original copy
        6. Restart Mirth Connect service
        7. Launch Administrator
        8. Verify if able to launch and login

        Observation:
        Before fixes:

        1. After the above steps, mirth.properties file would get corrupted (file size changed from 4KB -> 6KB).
        2. See attached corrupted.mirth.properties file
        3. If user happens to restart Mirth Connect, user won't be able to log into Administrator with Error and this exception in Client (java) log
          com.mirth.connect.client.core.ClientException: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
          	at com.mirth.connect.client.core.ServerConnection.executeSync(ServerConnection.java:221)
          	at com.mirth.connect.client.core.ServerConnection.apply(ServerConnection.java:144)
          	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
          	at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:722)
          	at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
          	at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
          	at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
          	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
          	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:718)
          	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:459)
          	at org.glassfish.jersey.client.proxy.WebResourceFactory.invoke(WebResourceFactory.java:379)
          	at com.sun.proxy.$Proxy13.login(Unknown Source)
          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          	at java.lang.reflect.Method.invoke(Unknown Source)
          	at com.mirth.connect.client.core.Client$2.invoke(Client.java:249)
          	at com.sun.proxy.$Proxy13.login(Unknown Source)
          	at com.mirth.connect.client.core.Client.login(Client.java:301)
          	at com.mirth.connect.client.ui.LoginPanel$8.doInBackground(LoginPanel.java:425)
          	at com.mirth.connect.client.ui.LoginPanel$8.doInBackground(LoginPanel.java:412)
          	at javax.swing.SwingWorker$1.call(Unknown Source)
          	at java.util.concurrent.FutureTask.run(Unknown Source)
          	at javax.swing.SwingWorker.run(Unknown Source)
          	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
          	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
          	at java.lang.Thread.run(Unknown Source)

        Verify Fixed:
        With the latest revision:

        1. Server Manager prompted to overwrite before "Apply" changes in Server Manager
        2. mirth.properties file was updated properly, no corruption found
        3. Even when a corrupted mirth.properties file is in place (copy from older build), was still be able to log into Administrator Console, Exception in Client (java) log
          Exception in thread "AWT-EventQueue-2" java.lang.NullPointerException
          	at javax.swing.plaf.basic.BasicTextFieldUI.getBaseline(Unknown Source)
          	at javax.swing.JComponent.getBaseline(Unknown Source)
          	at javax.swing.GroupLayout$ComponentSpring.getBaseline(Unknown Source)
          	at javax.swing.GroupLayout$BaselineGroup.calculateBaselineAndResizeBehavior(Unknown Source)
          	at javax.swing.GroupLayout$BaselineGroup.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout.calculateAutopadding(Unknown Source)
          	at javax.swing.GroupLayout.prepare(Unknown Source)
          	at javax.swing.GroupLayout.minimumLayoutSize(Unknown Source)
          	at java.awt.Container.minimumSize(Unknown Source)
          	at java.awt.Container.getMinimumSize(Unknown Source)
          	at javax.swing.JComponent.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ComponentSpring.calculateNonlinkedMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ComponentSpring.calculateMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source)
          	at javax.swing.GroupLayout$ComponentSpring.calculatePreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculatePreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculateSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.calculatePreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source)
          	at javax.swing.GroupLayout$SequentialGroup.setValidSize(Unknown Source)
          	at javax.swing.GroupLayout$Group.setSize(Unknown Source)
          	at javax.swing.GroupLayout.layoutContainer(Unknown Source)
          	at java.awt.Container.layout(Unknown Source)
          	at java.awt.Container.doLayout(Unknown Source)
          	at java.awt.Container.validateTree(Unknown Source)
          	at java.awt.Container.validateTree(Unknown Source)
          	at java.awt.Container.validateTree(Unknown Source)
          	at java.awt.Container.validateTree(Unknown Source)
          	at java.awt.Container.validate(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)
        4. Also observed no corruption with log4j.properties when making changes via Text Editor
        Show
        Minh Tran added a comment - - edited OS(s) and JRE version: virtual Window 7 with JRE version 1.8.0_91-b14 Version(s)/Build(s) to reproduce failure: mirthconnect-3.4.1.8057.b139-windows-x64 Version(s)/Build(s) to verify fixes: mirthconnect-3.5.0.8075.b1998-windows-x64.exe How Tested: Launch & Open Mirth Connect Server Manager From Window Explorer, go to <mirth install>/conf/, make a copy of mirth.properties (save as .original) Open mirth.properties in editor, make some comments, save changes and exit editor Back to Server Manager, make changes to Server > Log Level > select Apply Verify content of the current mirth.properties vs. the original copy Restart Mirth Connect service Launch Administrator Verify if able to launch and login Observation: Before fixes: After the above steps, mirth.properties file would get corrupted (file size changed from 4KB -> 6KB). See attached corrupted.mirth.properties file If user happens to restart Mirth Connect, user won't be able to log into Administrator with Error and this exception in Client (java) log com.mirth.connect.client.core.ClientException: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) at com.mirth.connect.client.core.ServerConnection.executeSync(ServerConnection.java:221) at com.mirth.connect.client.core.ServerConnection.apply(ServerConnection.java:144) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255) at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:722) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:228) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:718) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:459) at org.glassfish.jersey.client.proxy.WebResourceFactory.invoke(WebResourceFactory.java:379) at com.sun.proxy.$Proxy13.login(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.mirth.connect.client.core.Client$2.invoke(Client.java:249) at com.sun.proxy.$Proxy13.login(Unknown Source) at com.mirth.connect.client.core.Client.login(Client.java:301) at com.mirth.connect.client.ui.LoginPanel$8.doInBackground(LoginPanel.java:425) at com.mirth.connect.client.ui.LoginPanel$8.doInBackground(LoginPanel.java:412) at javax.swing.SwingWorker$1.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at javax.swing.SwingWorker.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang. Thread .run(Unknown Source) Verify Fixed: With the latest revision: Server Manager prompted to overwrite before "Apply" changes in Server Manager mirth.properties file was updated properly, no corruption found Even when a corrupted mirth.properties file is in place (copy from older build), was still be able to log into Administrator Console, Exception in Client (java) log Exception in thread "AWT-EventQueue-2" java.lang.NullPointerException at javax.swing.plaf.basic.BasicTextFieldUI.getBaseline(Unknown Source) at javax.swing.JComponent.getBaseline(Unknown Source) at javax.swing.GroupLayout$ComponentSpring.getBaseline(Unknown Source) at javax.swing.GroupLayout$BaselineGroup.calculateBaselineAndResizeBehavior(Unknown Source) at javax.swing.GroupLayout$BaselineGroup.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$ParallelGroup.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout.calculateAutopadding(Unknown Source) at javax.swing.GroupLayout.prepare(Unknown Source) at javax.swing.GroupLayout.minimumLayoutSize(Unknown Source) at java.awt.Container.minimumSize(Unknown Source) at java.awt.Container.getMinimumSize(Unknown Source) at javax.swing.JComponent.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$ComponentSpring.calculateNonlinkedMinimumSize(Unknown Source) at javax.swing.GroupLayout$ComponentSpring.calculateMinimumSize(Unknown Source) at javax.swing.GroupLayout$Spring.getMinimumSize(Unknown Source) at javax.swing.GroupLayout$ComponentSpring.calculatePreferredSize(Unknown Source) at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculatePreferredSize(Unknown Source) at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source) at javax.swing.GroupLayout$Group.getSpringSize(Unknown Source) at javax.swing.GroupLayout$Group.calculateSize(Unknown Source) at javax.swing.GroupLayout$Group.calculatePreferredSize(Unknown Source) at javax.swing.GroupLayout$Spring.getPreferredSize(Unknown Source) at javax.swing.GroupLayout$SequentialGroup.setValidSize(Unknown Source) at javax.swing.GroupLayout$Group.setSize(Unknown Source) at javax.swing.GroupLayout.layoutContainer(Unknown Source) at java.awt.Container.layout(Unknown Source) at java.awt.Container.doLayout(Unknown Source) at java.awt.Container.validateTree(Unknown Source) at java.awt.Container.validateTree(Unknown Source) at java.awt.Container.validateTree(Unknown Source) at java.awt.Container.validateTree(Unknown Source) at java.awt.Container.validate(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) Also observed no corruption with log4j.properties when making changes via Text Editor
        Hide
        Minh Tran added a comment -

        Verified with mirthconnect-3.5.0.8075.b1998-windows-x64.exe

        1. mirth.properties wont get corrupted when make changes via Text Editor and Server Manager
        2. Server Manager will now prompt for Overwrite when there are changes to mirth.properties file
        3. User still able to log into Administrator even when mirth.properties corrupted (with multiple lines of protocol/cipher suite)
        Show
        Minh Tran added a comment - Verified with mirthconnect-3.5.0.8075.b1998-windows-x64.exe mirth.properties wont get corrupted when make changes via Text Editor and Server Manager Server Manager will now prompt for Overwrite when there are changes to mirth.properties file User still able to log into Administrator even when mirth.properties corrupted (with multiple lines of protocol/cipher suite)

          People

          • Assignee:
            Nick Rupley
            Reporter:
            Nick Rupley
            Assigned QA:
            Minh Tran
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development