Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can not access Record via property in EL #25052

Open
hantsy opened this issue Jul 16, 2024 · 8 comments
Open

Can not access Record via property in EL #25052

hantsy opened this issue Jul 16, 2024 · 8 comments

Comments

@hantsy
Copy link

hantsy commented Jul 16, 2024

Environment Details

  • GlassFish Version (and build number): 8.0.0-M6
  • JDK version: 21
  • OS: Windows 10 Pro
  • Database: built-in(not used it in this example project)

Problem Description

EL 6.0 supports record, but I have tried in a simple facelets page, failed to access the property.

...faces-examples/customer.xhtml: The class 'com.example.Customer' 
does not have the property 'firstName'.

The example project: https://github.com/hantsy/jakartaee11-sandbox/tree/master/faces

The back bean:

@RequestScoped
@Named
public class CustomerBean {
    private final static Logger LOGGER= Logger.getLogger(CustomerBean.class.getName());

    @Inject
    FacesContext facesContext;

    private Customer customer;

    public Customer getCustomer() {
        return customer;
    }

    //@PostConstruct
    // use faces event to initialize it
    public void init(PreRenderViewEvent event) {
        if(facesContext.isPostback()){
            LOGGER.log(Level.INFO, "postback, skipping initialization");
            return;
        }

        LOGGER.log(Level.INFO, "initializing");
        customer = new Customer(
                "Foo",
                "Bar",
                new EmailAddress[]{
                        new EmailAddress("[email protected]", true),
                        new EmailAddress("[email protected]", false)
                },
                new Address("123 Main St", "Anytown", "CA", "12345")
        );
        LOGGER.log(Level.INFO, "initialized");
    }
}

public record Customer(
        String firstName,
        String lastName,
        EmailAddress[] emailAddresses,
        Address address
) {
}
record EmailAddress(
        String email,
        Boolean primary
) {
}
record Address(
        String street,
        String city,
        String state,
        String zipCode
) {
}

The facelets template:

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="jakarta.faces.facelets"
      xmlns:f="jakarta.faces.core"
      xmlns:h="jakarta.faces.html">
<f:view>
    <f:metadata>
        <f:event listener="#{customerBean.init}" type="preRenderView"/>
    </f:metadata>
    <h:head>
        <title>Express Language 6.0!</title>
    </h:head>
    <h:body>
        <h1>Express Language 6.0</h1>

        <div>
            <strong>#{customerBean.customer.firstName +' ' +customerBean.customer.lastName}</strong>
            <hr/>
        </div>
        <div>Emails: (#{customerBean.customer.emailAddresses.length})</div>
        <ul>
            <ui:repeat value="#{customerBean.customer.emailAddresses}" var="email">
                <li>#{email.email}(#{email.primary?'O':'X'})</li>
            </ui:repeat>
        </ul>
        <div>
            #{customerBean.customer.address.street},
            #{customerBean.customer.address.city},
            #{customerBean.customer.address.state},
            #{customerBean.customer.address.zipCode},
        </div>
    </h:body>
</f:view>
</html>
@arjantijms
Copy link
Contributor

As a quick test, within GF (in a servlet, bean, whatever) you could try invoking Expression Language "manually" (using the universal Java SE way) to see if records work. Normally the RecordELResolver should be added just before the BeanELResolver.

Start with

ELProcessor elProcessor = new ELProcessor();

And then work with that on your types (just as a smoke test)

Tbh, I did not take a look whether extra setup is required in Mojarra. There probably is.

@hantsy
Copy link
Author

hantsy commented Jul 17, 2024

@arjantijms
Copy link
Contributor

Thank you very much, so the API and optionally perhaps Expressly works correct here.

I'll have to figure out where to add it in mojarra

@hantsy
Copy link
Author

hantsy commented Aug 10, 2024

@arjantijms Still failed in Glassfish 8.0.0-M7

@arjantijms
Copy link
Contributor

@hantsy the following line in your example will crash any way:

<strong>#{customerBean.customer.firstName +' ' +customerBean.customer.lastName}</strong>

Removing that and with the latest 4.1.2-SNAPSHOT it does seem to work.

faces_el6

eclipse-ee4j/mojarra#5481

@OndroMih
Copy link
Contributor

In <strong>#{customerBean.customer.firstName +' ' +customerBean.customer.lastName}</strong>, plain + should be replaced with +=, which is an operator for string concatenation. Then it should work. Plain + only works with numbers.

@hantsy
Copy link
Author

hantsy commented Aug 13, 2024

Sorry, I forgot to update this. But here it indicated some info similar to can not access property customer.firstName, so I thought the EL resolver for record was still not applied.

@arjantijms
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants