Hello i was migrating from drools from 5.1.0 to 7.66.0.FINAL, it is working properly on .drl files but .rf files are probably not loaded correctly.
here is my old core 5.1.0 to load .drl and .rf
private KnowledgeBase computationKnowledgeBase;
public void loadDrls() {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(newReaderResource("Calc.drl"), ResourceType.DRL);
kbuilder.add(newReaderResource("Calc.rf"), ResourceType.DRF);
if (kbuilder.hasErrors()) {
this.log.error(kbuilder.getErrors().toString());
}
this.computationKnowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(KnowledgeBaseFactory.newKnowledgeBaseConfiguration());
this.computationKnowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());
StatefulKnowledgeSession session = this.computationKnowledgeBase.newStatefulKnowledgeSession();
if (log.isDebugEnabled()) {
session.addEventListener(new LoggingAgendaEventListener(log));
}
session.insert(something);
session.insert(something2);
session.fireAllRules();
session.dispose();
}
}
here is my 7.66.0 code:
here is my old core 5.1.0 to load .drl and .rf
private KieBase computationKnowledgeBase;
public void loadDrls() {
KieBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(KnowledgeBaseFactory.newKnowledgeBaseConfiguration());
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(knowledgeBase);
kbuilder.add(newReaderResource("Calc.drl"), ResourceType.DRL);
kbuilder.add(newReaderResource("Calc.rf"), ResourceType.DRF);
if (kbuilder.hasErrors()) {
log.error(kbuilder.getErrors().toString());
}
this.computationKnowledgeBase = knowledgeBase;
StatefulKnowledgeSession session = (StatefulKnowledgeSession) this.rulesCache.getCalculationKnowledgeBase().newKieSession();
session.insert(something);
session.insert(something2);
session.fireAllRules();
session.dispose();
}
dependency:
<!-- Drools -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
<exclusions>
<exclusion>
<artifactId>jxl</artifactId>
<groupId>net.sourceforge.jexcelapi</groupId>
</exclusion>
</exclusions>
</dependency>
problem is that it does load .rf file but it does not working properly (on .rl file we've got order of rules and it does not execute in correct order how it worked on older drools)
EDIT:
I have updated code with sessions, problem is that in new drools there are not StateFullKnowledgeSession only newKieSession.
Problem with this is that on .rf file i have order of execution rule methods, but when i upgrades it like this, drools are working but order of execution (defined on .rf file) is not working properly.
EDIT2:
it is related to this answer, on drools v5 it is executing .rf correctly
on v 7.66.FINAL it is executing on reverse order
https://github.com/tenkyu/drools-flow-order
https://groups.google.com/g/drools-usage/c/GK5OPUXQl5Q/m/NZQFVsYvBQAJ
Has anybody had this problem?
SOLUTION:
downgrade drools to 6.4.0 version, it is version where .rf files are not executing in reverse order
Related
Statement of problem:
I am refactoring my application from Spring 5.x to Spring 6.0.0 .
Due to changes in the java API's imposed by Oracle, some dependencies have been forced to be changed.
There appears to be a dependency conflict where the org.springframework.jms.listener.MessageListenerContainer requires a jakarta.jms.ConnectionFactory, but the org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory extends the older javax.jms.ConnectionFactory .
I suspect that there is a POM dependency that I am missing, but I have been unable to resolve it.
POM excerpt:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-xml</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-flow</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jms</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<version>2.27.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-spring-integration</artifactId>
<version>2.27.1</version>
</dependency>
Code Snip:
// ActiveMQConnectionFactory implements javax.jms.ConnectionFactory
#Order(0)
public ActiveMQConnectionFactory connectionFactory() throws JMSException {
if (connectionFactory == null) {
connectionFactory = new ActiveMQConnectionFactory();
PropertyValue pv = configPropertiesService.fetchPropertyValue(PropertyValueConstants.ACTIVEMQ_BROKER_URL,
PropertyValueConstants.ACTIVEMQ_BROKER_URL_DEFAULT);
PropertyValue pvu = configPropertiesService.fetchPropertyValue(PropertyValueConstants.ACTIVEMQ_BROKER_UNAME,
PropertyValueConstants.ACTIVEMQ_BROKER_USERNAME_DEFAULT);
PropertyValue pvp = configPropertiesService.fetchPropertyValue(PropertyValueConstants.ACTIVEMQ_BROKER_PASS,
PropertyValueConstants.ACTIVEMQ_BROKER_PASS_DEFAULT);
connectionFactory.setBrokerURL(pv.getValue());
connectionFactory.setPassword(pvp.getValue());
}
return connectionFactory;
}
#Bean(name = "MessageDrivenAdapter")
public MessageListenerContainer getContainer() {
DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
container.setConnectionFactory(connectionFactory()); // requires jakarta.jms.ConnectionFactory
container.setDestinationName("requestsQueue");
container.setMessageListener(messageListener());
container.setAutoStartup(false);
container.setTaskExecutor(stepTaskExecutor);
container.setConcurrentConsumers(5);
return container;
}
ActiveMQ developers provide two flavours of their library (seems to be the most sober approach for that messy javax -> jakarta transition):
ActiveMQ Artemis JMS Client - compatible with Java EE API (javax. namespace)
ActiveMQ Artemis Jakarta Messaging Client - compatible with JakartaEE 9 API (jakarta. namespace)
You need the second one.
So I was using Open Tracing to trace calls to the microservice. I used to do it the following way:
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
<version>0.31.0</version>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-cloud-starter</artifactId>
<version>0.1.13</version>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-client</artifactId>
<version>0.31.0</version>
</dependency>
Then add following bean:
#Bean
public Tracer initTracer() {
Configuration.SamplerConfiguration samplerConfig = new Configuration.SamplerConfiguration().withType("const").withParam(1);
Configuration.ReporterConfiguration reporterConfig = Configuration.ReporterConfiguration.fromEnv().withLogSpans(true);
return Configuration.fromEnv("my-service").withSampler(samplerConfig).withReporter(reporterConfig).getTracer();
}
When running I usually get these span reported logs whenever an external request is given to the application.
But with open telemetry I cannot simply do this anymore. What is the correct way to simulate the behaviour?
I am implementing Server Sent Events with Jersey 2.28 and I can't get the basic examples to work.
Other answers mention a dependency problem, I've added all the necessary dependencies to no avail:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-sse</artifactId>
</dependency>
</dependencies>
I basically copy-pasted the example and ran it, I've tried variations found in tutorials such as https://www.baeldung.com/java-ee-jax-rs-sse but it just won't work
#GET
#Path("/locations")
#Produces(MediaType.SERVER_SENT_EVENTS)
public void getServerSentEvents(#Context SseEventSink eventSink, #Context Sse sse) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
final OutboundSseEvent event = sse.newEventBuilder().name("message-to-client")
.data(String.class, "Hello world " + i + "!").build();
eventSink.send(event);
}
}).start();
}
Can anyone provide me with the correct implementation for basic SSE using Jersey (I'm using the grizzly implementation)
I'm having trouble creating a JUnit test using a pom.xml dependency.
The test are being run with Arquillian
#RunWith(Arquillian.class)
In this method
#Deployment
public static JavaArchive createDeployment() {
First, I create a JavaArchive with the package of the project I'm testing
JavaArchive merge = ShrinkWrap.create(JavaArchive.class).
addPackages(true,
"migrazioneGeaPersistenzaTampone",
"migrazioneGeaPersistenza",
"it.**.mistral.importGEA4.task",
"migrazioneGeaPersistenzaAccess"
).
addClasses(java.sql.Connection.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
Then when I launch the test, there are some missing dependencies
Unable to resolve any beans for Types: [class it.**.**.be.service.EnvironmentRootService]
present in this dependency
<dependency>
<groupId>it.**.mistral</groupId>
<artifactId>mistral-be</artifactId>
<version>0.1.0</version>
<scope>compile</scope>
</dependency>
I have tried lots of different things to add these dependencies, the best one seems to be using the ShrinkWrap Resolvers (https://github.com/shrinkwrap/resolver/blob/master/README.asciidoc, particullarry this paragraph https://github.com/shrinkwrap/resolver/blob/master/README.asciidoc#resolution-of-artifacts-defined-in-pom-files)
a)
JavaArchive[] archives = Maven.resolver().loadPomFromFile(path_to_pom_file).
importDependencies(ScopeType.TEST,ScopeType.COMPILE).
resolve().withTransitivity().as(JavaArchive.class);
or
Maven.resolver().loadPomFromFile("/path/to/pom.xml").importRuntimeDependencies()
.resolve().withTransitivity().asFile();
The dependency is ignored in either way (i'm missing something?)
b)
JavaArchive[] mistral_be = Maven.configureResolver().workOffline().
resolve("it.**.mistral:mistral-be:0.1.0").withTransitivity().as(JavaArchive.class);
for (int i = 0; i < mistral_be.length ; i++) {
merge = merge.merge(mistral_be[i]);
}
With a simple
System.out.println(merge.toString(true));
I can see that all files from dependencies are present! Anyway I use local repository workoffline()
Maybe I am missing some dependencies?
But exiting the method with a
return merge;
throws a "java.lang.NoClassDefFoundError: com/google/protobuf/GeneratedMessage....Caused by: java.lang.ClassNotFoundException: com.google.protobuf.GeneratedMessage" error.
Then again i tried to add the missing dependecies
// Tryn'g to add protobuf dependencies
JavaArchive[] prto_buf = Maven.configureResolver().withMavenCentralRepo(true).resolve("com.google.protobuf:protobuf-java:2.3.0").withTransitivity().as(JavaArchive.class);
for (int i = 0; i < prto_buf.length ; i++) {
projectPackages = projectPackages.merge(prto_buf[i]);
}
Throws sameException...
Again , with a simple
System.out.println(merge.toString(true));
I can see that com.Google.protobuf.GeneratedMessage is present
Extract of dependencies:
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.5.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
Can anybody help me solve this issue?
This smells to me like a classloading issue. Especially considering the fact that you are using embedded container which basically takes everything what's in there from your project classpath.
What is your target container you are deploying your application on? Maybe if you try to run your test there instead of embedded container you will at least see if that is really the problem, or there is still something wrong with your deployment artifact.
Just taking Spring-Boot for a spin and decided to mix in Camel because I need some arcane Headers work in the rest client I am working on. Setting up the application was fine until I added the camel-http component to my POM, then I get this on init:
Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
I've havent got the first idea of where to start to look for the problem. I gather Spring Boot will look up the classpath and try to wire stuff up, so is there a way for the to block the Camel packages from being acted on or something of the sort?
Complete log of the start up in this Gist
Here's my main aplication code:
#ComponentScan
#EnableAutoConfiguration
public class Application {
private static ApplicationContext ctx;
public static void main(String[] args) throws Exception {
ctx = SpringApplication.run(Application.class, args);
//Right outta Spring 4 docs
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
//---
// FIXME: ugly hack to allow some POC woek while wait for proper Camel/Spring4 unit tests fix.
Application app = new Application();
app.executeTests();
}
/**
* Dev QOL - unit tests are broken for now, see:
* https://issues.apache.org/jira/browse/CAMEL-7074
* <p/>
* Waiting for fix (Too lay to checkout and build my own Camel)
*/
private void executeTests() throws Exception {
testAuth();
}
#Bean
DefaultCamelContext camelCtx() throws Exception {
DefaultCamelContext camel = new DefaultCamelContext();
camel.addRoutes(cryptsyRouteBuilder());
camel.start();
return camel;
}
#Bean
public CryptsyRouteBuilder cryptsyRouteBuilder() throws Exception{
CryptsyRouteBuilder bean = new CryptsyRouteBuilder();
bean.setCryptsy(cryptsy());
return bean;
}
#Bean
public Cryptsy cryptsy() throws IOException {
return new Cryptsy();
}
protected void testAuth() throws Exception {
ProducerTemplate producer = camelCtx().createProducerTemplate();
producer.requestBody("direct:start", "Why, hullo there", String.class);
}
}
And my POM dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>0.5.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-actuator</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- Camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-javaconfig</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- Assorted -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
<properties>
<start-class>xxx.xxxx.Application</start-class>
<camel.version>2.12.2</camel.version>
</properties>
The exception is telling you that Spring Boot thinks you want to build a web server, but can't find the right dependencies on the classpath. The most obvious reason for that in your case would be that the HTTP dependencies you added included Servlet APIs. I see no reason why you need that for a client app, but only you would know whether you need it or not. Maybe you can exclude it?
If you do need the Servlet dependencies and just want to explicitly tell Boot that you aren't creating a web application you can set the property spring.main.web_environment=false, or use the SpringApplication (or SpringApplicationBuilder) API directly to set the same flag. See docs here for background information.