Hot questions for Using Enterprise JavaBeans in annotations

Question:

I have a project where many classes have one and the same simple name, but are decorated with different annotations.

For example:

package com.example.base;

@Default
public class ClassName { }

and

package com.example.country;

@SomeCountrySpecific
public class ClassName extends com.example.base.ClassName { }

There are many classes like these within the project and all are EJB injected within other classes' constructors/setters.

In IntelliJ, when I want to navigate to some class, I can type only the class name and the IDE finds all the classes and gives back a list of options. You can imagine that this lists often consists of more than 15-20 different classes and navigating and finding the desired one is difficult.

However, I would like to open a class, which has a name equal to ClassName and is annotated with some annotation (like @SomeCountrySpecific).

Is this possible in IntelliJ?

Please note that renaming the sub-classes is not an option.


Answer:

It's not very elegant or all that convenient, but this might get you what you're looking for (?). You can use the file mask and "Text to find" to search for annotations in files named by some pattern.

Question:

I have an object class like which has no required field except Id. here is the code:

Entity
@XmlRootElement
@Table(name = "T_HOST_SPEC")
@Cacheable(false)
@NamedQueries({
    @NamedQuery(name = HostSpec.FIND_ALL, query = "SELECT m FROM HostSpec m")
    ,@NamedQuery(name = HostSpec.FIND_BY_IP_CONTEXT_PATH_PORT, query = "SELECT m FROM HostSpec m WHERE m.ip = :ip AND m.contextPath =:contextPath AND m.port =:port ")})
public class HostSpec extends AbstractEntity {



    @Id
    @SequenceGenerator(name = "HOST_SPEC_SEQUENCE_GENERATOR", sequenceName = "HOST_SPEC_SEQ", initialValue = 1, allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HOST_SPEC_SEQUENCE_GENERATOR")
    @XmlElement(name = "id")
    @NotNull
    @Column(name = "ID", nullable = false)
    private Long id;

    @Size(max =200 )
    @Column(name = "APP_NAME",length = 25)
    @XmlElement(name = "APP_NAME")
    private String appName;

    @Size(max =1000 )
    @Column(name = "APP_SERVER_INFO",length = 25)
    @XmlElement(name = "APP_SERVER_INFO")
    private String serverInfo;

    @Size(max =100 )
    @Column(name = "CONTEXT_PATH",length = 25)
    @XmlElement(name = "CONTEXT_PATH")
    private String contextPath;

    @Size(max =255 )
    @Column(name = "BUILD_DATE",length = 25)
    @XmlElement(name = "BUILD_DATE")
    private String buildDate;

    @Size(max =4000 )
    @Column(name = "DESCRIPTION",length = 25)
    @XmlElement(name = "DESCRIPTION")
    private String description;


    @Size(max =50 )
    @Column(name = "IP",length = 25)
    @XmlElement(name = "IP")
    private String ip;

    @Size(max =200 )
    @Column(name = "MODULE_NAME",length = 25)
    @XmlElement(name = "MODULE_NAME")
    private String moduleName;

    @Size(max =100 )
    @Column(name = "NAME",length = 25)
    @XmlElement(name = "NAME")
    private String name;

    @Size(max = 10)
    @XmlElement(name = "PORT")
    @Column(name = "PORT")
    private Long port;

    @Size(max =20 )
    @Column(name = "PROTOCOL",length = 25)
    @XmlElement(name = "PROTOCOL")
    private String protocol;


    @Size(max = 10)
    @XmlElement(name = "VERSION_CODE")
    @Column(name = "VERSION_CODE")
    private Long versionCode;

    @Size(max =100 )
    @Column(name = "VERSION_NAME",length = 25)
    @XmlElement(name = "VERSION_NAME")
    private String versionName;

    @Size(max =100 )
    @Column(name = "VIRTUAL_SERVER_NAME",length = 25)
    @XmlElement(name = "VIRTUAL_SERVER_NAME")
    private String serverName;

//getters & setters

when I try to run it, this exception is throws: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.lang.Long please help


Answer:

@Size is not intended to be used on type Long (you shall use @Max in this case).

Hence, you should replace @Size(max = 10) with the corresponding @Max annotation on fields port and versionCode

According to the javadoc, @Size can be used on following types :

  • String (string length is evaludated)
  • Collection (collection size is evaluated)
  • Map (map size is evaluated)
  • Array (array length is evaluated)
  • null elements are considered valid.

Question:

I am trying to get the EJB Observer pattern to work and it seems very straight forward from examples like this:

http://www.devchronicles.com/2011/11/javaee-revisits-design-patterns_28.html

however when I implement the method:

public void doLogging(@Observes String message){
    System.out.println("Observed:"+message);
}

the @Observer annotation import does not get inserted.

Also if I do it manually as:

import javax.enterprise.event.Observes;

it does not work looking like I do not have the classes/jars.

I am using EJB 3.0 and am hoping this is not present only in 3.1. If this is the case how can i get the Observer pattern in EJB 3.0?


Answer:

It's not part of EJB, but of CDI (JSR-299).

CDI is new since Java EE 6, which also covers EJB 3.1. As you've only EJB 3.0 at hands, this means that you're still on Java EE 5. These days we're already at Java EE 7. It's about time to upgrade.

Examples of Java EE 7 servers are JBoss WildFly 8.x, Oracle GlassFish 4.x, Apache TomEE 2.x and IBM WebSphere 9.x. Examples of Java EE 6 servers are JBoss AS 6.x/7.x, Oracle GlassFish 3.x, Apache TomEE 1.x and IBM WebSphere 8.x.

See also:
  • What is Weld, JSR-299?

Question:

Got an issue today when trying to use a Java @Schedule annotation on one of my methods. Error is as follows:

Severe:   Exception while deploying the app [MyApp-ear] : Error processing EjbDescriptor
java.lang.RuntimeException: ScheduleManager: Invalid schedule defined on method sendEmail(): Invalid minute value: ?
at org.glassfish.ejb.deployment.util.EjbBundleValidator.accept(EjbBundleValidator.java:351)
at org.glassfish.ejb.deployment.descriptor.EjbDescriptor.visit(EjbDescriptor.java:2855)
at org.glassfish.ejb.deployment.descriptor.EjbDescriptor.visit(EjbDescriptor.java:2843)
at org.glassfish.ejb.deployment.util.EjbBundleValidator.accept(EjbBundleValidator.java:115)
at com.sun.enterprise.deployment.BundleDescriptor.visit(BundleDescriptor.java:627)
at org.glassfish.ejb.deployment.descriptor.EjbBundleDescriptorImpl.visit(EjbBundleDescriptorImpl.java:767)
at com.sun.enterprise.deployment.util.ApplicationValidator.accept(ApplicationValidator.java:121)
at com.sun.enterprise.deployment.BundleDescriptor.visit(BundleDescriptor.java:627)
at com.sun.enterprise.deployment.archivist.ApplicationArchivist.validate(ApplicationArchivist.java:703)
at com.sun.enterprise.deployment.archivist.ApplicationArchivist.openWith(ApplicationArchivist.java:248)
at com.sun.enterprise.deployment.archivist.ApplicationFactory.openWith(ApplicationFactory.java:232)
at org.glassfish.javaee.core.deployment.DolProvider.processDOL(DolProvider.java:189)
at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:223)
at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:91)
at com.sun.enterprise.v3.server.ApplicationLifecycle.loadDeployer(ApplicationLifecycle.java:882)
at com.sun.enterprise.v3.server.ApplicationLifecycle.setupContainerInfos(ApplicationLifecycle.java:822)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:378)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:220)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:487)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)

My method declaration looks like this:

@Schedule(minute = "∗/5")
public void sendEmail() {
  //Send email here
}

Any idea what could be causing this? I've used this many a time and never had any problems but mostly used the "dayOfMonth" attribute. I found the expression that I was looking for on the Oracle Docs for @Schedule to run every 5 minutes on the hour.


Answer:

The * char was invalid, but you already noticed that :)

Important hint: your scheduling is still wrong!

When not specifying any of the annotation's parameters, it will fall back to the default value. The default value for hour is 0, meaning that your scheduled task will run every 5 minutes from 00:05 to 00:55, and then be idle for the next 23 hours.

To fix this, also specify the hours as *:

@Schedule(hour = "*", minute = "*/5")

See default values in Schedule:

public @interface Schedule {

    String second() default "0";
    String minute() default "0";
    String hour() default "0";