groovy

Write-only JavaBeans properties cannot be set via the '=' operator

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.1-rc-1
  • Fix Version/s: 1.6-rc-2
  • Component/s: bytecode
  • Labels:
    None
  • Testcase included:
    yes
  • Number of attachments :
    0

Description

This code works well:

def frame = new JFrame()
frame.setLocationRelativeTo(null)

But this one throws exception:

def frame = new JFrame()
frame.locationRelativeTo = null

But it is possible to use locationRelativeTo in SwingBuilder, like if
it is existing property.

Example:

def swing = new SwingBuilder()

def frame = swing.frame(
title: "Cool Groovy Frame",
defaultCloseOperation: JFrame.EXIT_ON_CLOSE,
preferredSize: [400, 400],
size: [400, 400],
locationRelativeTo: null,
) { .... }

Issue Links

Activity

Hide
Sergey Bondarenko added a comment -

Danno Ferrin (<danno.ferrin@shemnon.com>) wrote also:

There are at least three write only properties missed on JFrame...

java.beans.Introspector.getBeanInfo(javax.swing.JFrame).propertyDescriptors.collect {it.name} - new javax.swing.JFrame().properties.keySet()

Result: ["component", "focusTraversalKeys", "locationRelativeTo"]

Show
Sergey Bondarenko added a comment - Danno Ferrin (<danno.ferrin@shemnon.com>) wrote also: There are at least three write only properties missed on JFrame... java.beans.Introspector.getBeanInfo(javax.swing.JFrame).propertyDescriptors.collect {it.name} - new javax.swing.JFrame().properties.keySet() Result: ["component", "focusTraversalKeys", "locationRelativeTo"]
Hide
Danno Ferrin added a comment - - edited

After a bit of investigation some refinement is needed...

The property locationRelativeTo is being reflected (new javax.swing.JFrame().metaClass.properties.findAll{it.name == 'locationRelativeTo'} returns the metaProperty)

However, there is an error in the code that does writes...

new javax.swing.JFrame().locationRelativeTo = null

This code (for a reason I don't understand) attempts to call ScriptByteCodeAdapter.getProperty(Class, Object, String). This call fails because locationRelativeTo has no getter, just a setter. It is being mis-reported to the end user as the property not existing. We need to get rid of that spurrious call to setProperty for writeonly properties.

Also, component and focusTraversalKeys are a red hearing. They are indexed JavaBeansProperties (i.e. getFoo(int), setFoo(int, type)) and are reflected as such by the introspector. If we want to support these a separate JIRA should be raised, as an enhancement for 1.2/2.0.

Since it is a bytecode generation issue I'll throw this in Jochen's queue as a high (not blocker since SwingBuilder can get at it fine)

Show
Danno Ferrin added a comment - - edited After a bit of investigation some refinement is needed... The property locationRelativeTo is being reflected (new javax.swing.JFrame().metaClass.properties.findAll{it.name == 'locationRelativeTo'} returns the metaProperty) However, there is an error in the code that does writes...
new javax.swing.JFrame().locationRelativeTo = null
This code (for a reason I don't understand) attempts to call ScriptByteCodeAdapter.getProperty(Class, Object, String). This call fails because locationRelativeTo has no getter, just a setter. It is being mis-reported to the end user as the property not existing. We need to get rid of that spurrious call to setProperty for writeonly properties. Also, component and focusTraversalKeys are a red hearing. They are indexed JavaBeansProperties (i.e. getFoo(int), setFoo(int, type)) and are reflected as such by the introspector. If we want to support these a separate JIRA should be raised, as an enhancement for 1.2/2.0. Since it is a bytecode generation issue I'll throw this in Jochen's queue as a high (not blocker since SwingBuilder can get at it fine)
Hide
Danno Ferrin added a comment - - edited

Test case

(outside main class)

public class WriteOnlyBean {
  public setWriteOnlyProperty(String s) {
    // ignore
  }
}

in unit test class

public void testWriteOnlyBeanProperty() {
    c = new WriteOnlyBean()

    // assert the property exists
    assert c.metaClass.properties.findAll{it.name == 'writeOnlyProperty'}

    // attempt to write to it
    c.writeOnlyProperty = 'x'
}
Show
Danno Ferrin added a comment - - edited Test case (outside main class)
public class WriteOnlyBean {
  public setWriteOnlyProperty(String s) {
    // ignore
  }
}
in unit test class
public void testWriteOnlyBeanProperty() {
    c = new WriteOnlyBean()

    // assert the property exists
    assert c.metaClass.properties.findAll{it.name == 'writeOnlyProperty'}

    // attempt to write to it
    c.writeOnlyProperty = 'x'
}
Hide
Paul King added a comment - - edited

If it is the error I have been trying to track down, another workaround is to place an additional dummy line after the expression which sets the write-only property. E.g., replace your last line with:

c.writeOnlyProperty = 'x'
return
Show
Paul King added a comment - - edited If it is the error I have been trying to track down, another workaround is to place an additional dummy line after the expression which sets the write-only property. E.g., replace your last line with:
c.writeOnlyProperty = 'x'
return
Hide
Paul King added a comment -

OK, just submitted a fix for this I think.
Jochen, can you check if it looks OK.
Danno, can you see if this fixes the Swing scenarios?

Show
Paul King added a comment - OK, just submitted a fix for this I think. Jochen, can you check if it looks OK. Danno, can you see if this fixes the Swing scenarios?
Hide
Danno Ferrin added a comment -

I don't entirely understand what the patch does, but it does indeed work. Resolved and closed.

Show
Danno Ferrin added a comment - I don't entirely understand what the patch does, but it does indeed work. Resolved and closed.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: