Inter-yard injection

Asked

Viewed 108 times

2

I have a Jar project, Helper, which has a process manager, where it controls the execution of etal threads. Where it receives an interface that performs the execution when triggered.

I have another Jar, Service project, which implements the Helper interface, and injects a Factory of the Service project itself.

Error occurs when code is executed

processor = statementProcFactory.getProduct(modelMessage.getProcessType());

when executed via Helper. I tested calling the Statementtoproceequeueable processMessage inside the Service Application, cruising the message, and it worked smoothly. The error occurs only when processMessage is called by Sqsqueuerunnable.

The structure of the Helper:

├── src
│   ├── main
│   │   ├── java
│   │   │   └── br
│   │   │       └── com
│   │   │           └── aws
│   │   │               └── sqs
│   │   │                   ├── ISQSDequeueable.java
│   │   │                   ├── SQSDequeueableException.java
│   │   │                   ├── SQSQueueManager.java
│   │   │                   └── SQSQueueRunnable.java
│   │   └── resources
│   │       └── META-INF
│   │           └── beans.xml

And the structure of the Service

├── src
│   ├── main
│   │   ├── java
│   │   │   └── br
│   │   │       └── com
│   │   │           └── reconciliation
│   │   │               ├── service
│   │   │               │   ├── Application.java
│   │   │               │   ├── MainService.java
│   │   │               │   └── statement
│   │   │               │       └── processor
│   │   │               │           ├── IStatementProcessor.java
│   │   │               │           ├── processors
│   │   │               │           │   ├── BanriProcessor.java
│   │   │               │           │   ├── CieloProcessor.java
│   │   │               │           │   ├── RedeCreditProcessor.java
│   │   │               │           │   └── RedeDebitProcessor.java
│   │   │               │           ├── StatementProcessorFactory.java
│   │   │               │           ├── StatementProcessorType.java
│   │   │               │           └── StatementProcessorTypeLiteral.java
│   │   │               └── sqsdequeueable
│   │   │                   ├── StatementToProcessDequeueable.java
│   │   │                   └── StatementToProcessModel.java
│   │   └── resources
│   │       ├── aws.properties
│   │       └── META-INF
│   │           └── beans.xml

Main do Service:

public static void main(String[] args) {
    timer = new Timer();
    timer.schedule(new EchoTask(), 0, 1000);

    Weld weld = new Weld();
    WeldContainer container = weld.initialize();
    Application application = container.instance().select(Application.class).get();
    application.run();
    weld.shutdown();
}

Casse Application:

@Singleton
public class Application {

    @Inject
    private SQSQueueManager queueManager;

    @Inject
    private Provider<StatementToProcessDequeueable> statementProcDequeueProvider;


    public void run() {

        queueManager.addSQSDequeueable(statementProcDequeueProvider.get());
    }
}

Sqsqueuemanager addSQSDequeueable method:

public void addSQSDequeueable(ISQSDequeueable dequeueable) {

    SQSQueueRunnable runnable = runnableProvider.get();

    runnable.setDequeueable(dequeueable);

    Thread th = new Thread(runnable);

    dictionaryDequeueables.put(dequeueable, runnable);

    dequeueable.startRunning();

    th.start();
}

Sqsrunnable run method:

public void run() {
    ReceiveMessageRequest request = new ReceiveMessageRequest(
            dequeueable.getQueue());

    do {

        List<Message> messages = sqsAmazon.receiveMessage(request)
                .getMessages();

        for (Message message : messages) {
            processed = true;

            Thread th = new Thread(new Runnable() {

                private Message message;

                public void run() {
                    try {
                        dequeueable.processMessage(message);
                    } catch (SQSDequeueableException e) {
                        // TODO Mover mensagem para fila de erros
                        e.printStackTrace();
                    }

                    sqsAmazon.deleteMessage(new DeleteMessageRequest(
                            dequeueable.getQueue(), message
                                    .getReceiptHandle()));
                }

                public Runnable setMessage(Message message) {
                    this.message = message;
                    return this;
                }

            }.setMessage(message));

            th.run();
        }

        try {
            Thread.sleep(this.getSleepThread());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (isRunning == false)
            dequeueable.stopRunning();

    } while (isRunning);
}

Statementtoprocess processMessage method that implements the Isqsdequeueable interface

public void processMessage(Message message) throws SQSDequeueableException {

    logger.debug("Processando mensagem");

    StatementToProcessModel modelMessage = this.generateModel(message.getBody());

    if (modelMessage != null) {
        processor = statementProcFactory.getProduct(modelMessage.getProcessType());

        logger.debug("Processor gerado: " + processor);

        if (processor != null) {

            Statement statement = new Statement();

            Retail retail = repoRetail.getRetailByID(modelMessage.getRetailId());

            List<OperationCard> operations = processor.process(
                    statement.getInputStream(), retail);

            for (OperationCard operation : operations) {

            }

        } else {
            throw new SQSDequeueableException(String.format(
                    "O tipo de processador %s está inválido", processor));
        }
    } else {
        logger.debug("Atributos inválidos da mensagem");

        throw new SQSDequeueableException(
                "Mensagem não possuí todos atributos necessários");
    }
}

Statementprocessorfactory class

@Singleton
public class StatementProcessorFactory {

@Inject
@Any
private Instance<IStatementProcessor> products;

public IStatementProcessor getProduct(String type) {
    StatementProcessorTypeLiteral literal = new StatementProcessorTypeLiteral(type);
    Instance<IStatementProcessor> typeProducts = products.select(literal);
    return typeProducts.get();
}
}

Statementprocessortypeliteral class

@SuppressWarnings("serial")
public class StatementProcessorTypeLiteral extends
    AnnotationLiteral<StatementProcessorType> implements StatementProcessorType {

private String type;

public StatementProcessorTypeLiteral(String type) {
    this.type = type;
}

public String value() {
    return type;
}
}

Statementprocessortype interface

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface StatementProcessorType {
    public String value();
}

Class that implements Istatmentprocessor and has Statementprocessortype Qualifier

@StatementProcessorType("Banri")
@Stateless
public class BanriProcessor implements IStatementProcessor {
    public List<OperationCard> process(InputStream statementFile, Retail retail) {
    // TODO Auto-generated method stub
    return null;
}

}

Error:

Exception in thread "Thread-2" org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Types: [interface br.com.agilebox.gestorfiscal.reconciliation.service.statement.processor.IStatementProcessor]; Bindings: [QualifierInstance{annotationClass=interface br.com.agilebox.gestorfiscal.reconciliation.service.statement.processor.StatementProcessorType, values={[BackedAnnotatedMethod] public abstract br.com.agilebox.gestorfiscal.reconciliation.service.statement.processor.StatementProcessorType.value()=Banri}, hashCode=-1507802905}, QualifierInstance{annotationClass=interface javax.enterprise.inject.Any, values={}, hashCode=-2093968819}]
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:854)
at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:75)
at br.com.agilebox.gestorfiscal.reconciliation.service.statement.processor.StatementProcessorFactory.getProduct(StatementProcessorFactory.java:19)
at br.com.agilebox.gestorfiscal.reconciliation.sqsdequeueable.StatementToProcessDequeueable.processMessage(StatementToProcessDequeueable.java:31)
at br.com.agilebox.gestorfisccal.aws.sqs.SQSQueueRunnable.run(SQSQueueRunnable.java:64)
at java.lang.Thread.run(Thread.java:745)

1 answer

1

Every jar you own Beans CDI to be injected must have a file beans.xml in the briefcase META-INF, in accordance with documentation.

It can be an empty file even. Try to put it in the two Jars.

  • Both projects have Beans.xml

  • @user11813 Sorry, no detailed project setup information is objectively not possible to help.

  • add more information that might help you understand the problem

  • One more comment, I realized now that if I run it works. If I debug no. Has any explanation??

  • @giovanibarili No ideas, Sorry... :(

  • I put an example code on github https://github.com/giovanibarili/InjectBetweenJars

  • I tested in Eclipse in all possible ways and really occur various and random injection errors. I put the same code class Main in class AppTest (Junit) and tested using mvn test and it works 100% of the time. It still doesn’t work if you run Junit through Eclipse. Anyway, the problem is related to the Eclipse classloader. No debug for you, Sorry...

  • @giovanibarili I forgot to mark you. See my comment above . That’s why I prefer the Spring more!

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.