I want to record video quiet and without preview in Android. So I choice MediaRecorder but I could record only without preview but what make me crazy is that when MediaRecorder start or stop it will with a sound dee.... I try many methods about that . But I think it perhaps sth related to the OS of the mobile. So I try JavaCV because I also want to have a Live function in my app.
But JavaCV spent me to too much time to solve some strange problems because it's my first time to do sth about C++ src and video.
Just compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.3' as the README.md ,I even can't build my apk.
Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK org/bytedeco/javacpp/macosx-x86_64/libusb-1.0.dylib
File1: /Users/wyx/.gradle/caches/modules-2/files-2.1/org.bytedeco.javacpp-presets/libfreenect/0.5.3-1.3/736d65a3ef042258429d8e7742128c411806b432/libfreenect-0.5.3-1.3-macosx-x86_64.jar
File2: /Users/wyx/.gradle/caches/modules-2/files-2.1/org.bytedeco.javacpp-presets/libdc1394/2.2.4-1.3/f1498dacc46162ab68faeb8d66cf02b96fe41c61/libdc1394-2.2.4-1.3-macosx-x86_64.jar
And then I modified it according this issuse
use this to repalce. It can build the apk. But the can't run.
android {
..............
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.properties'
pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.xml'
pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.properties'
pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.xml'
}
}
dependencies {
compile group: 'org.bytedeco', name: 'javacv', version: '1.3'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.2.1-1.3', classifier: 'android-x86'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.2.1-1.3', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.1.0-1.3', classifier: 'android-x86'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.1.0-1.3', classifier: 'android-arm'
}
My demo code VideoService which will invoke in MainActivity
package com.fs.fs.api;
import com.fs.fs.App;
import com.fs.fs.utils.DateUtils;
import com.fs.fs.utils.FileUtils;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FrameRecorder;
import java.util.Date;
/**
* Created by wyx on 2017/1/11.
*/
public class VideoService {
private FFmpegFrameRecorder mFrameRecorder;
private String path;
private VideoService() {
}
private static class SingletonHolder {
private static final VideoService INSTANCE = new VideoService();
}
public static VideoService getInstance() {
return SingletonHolder.INSTANCE;
}
public void startRecordVideo() {
String fileName = String.format("%s.%s", DateUtils.date2String(new Date(), "yyyyMMdd_HHmmss"), "mp4");
path = FileUtils.getExternalFullPath(App.getInstance(), fileName);
mFrameRecorder = new FFmpegFrameRecorder(path, 640, 480, 1);
mFrameRecorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
mFrameRecorder.setVideoOption("tune", "zerolatency");
mFrameRecorder.setVideoOption("preset", "ultrafast");
mFrameRecorder.setVideoOption("crf", "28");
mFrameRecorder.setVideoBitrate(300 * 1000);
mFrameRecorder.setFormat("mp4");
mFrameRecorder.setFrameRate(30);
mFrameRecorder.setAudioOption("crf", "0");
mFrameRecorder.setSampleRate(48 * 1000);
mFrameRecorder.setAudioBitrate(960 * 1000);
mFrameRecorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
try {
mFrameRecorder.start();
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
}
}
public void stop() {
if (mFrameRecorder != null) {
try {
mFrameRecorder.stop();
mFrameRecorder.release();
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
}
mFrameRecorder = null;
}
}
}
MainActivity
package com.fs.fs.activity;
import android.app.Activity;
import android.os.Bundle;
import com.fs.fs.R;
import com.fs.fs.api.VideoService;
import static java.lang.Thread.sleep;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoService.getInstance().startRecordVideo();
try {
sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
VideoService.getInstance().stop();
}
}
Error which make me want to cry.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.fs.fs, PID: 30259
java.lang.NoClassDefFoundError: java.lang.ClassNotFoundException: org.bytedeco.javacpp.avutil
at org.bytedeco.javacpp.Loader.load(Loader.java:590)
at org.bytedeco.javacpp.Loader.load(Loader.java:530)
at org.bytedeco.javacpp.avcodec$AVPacket.<clinit>(avcodec.java:1694)
at org.bytedeco.javacv.FFmpegFrameRecorder.<init>(FFmpegFrameRecorder.java:149)
at com.fs.fs.api.VideoService.startRecordVideo(VideoService.java:34)
at com.fs.fs.activity.MainActivity.onCreate(MainActivity.java:75)
at android.app.Activity.performCreate(Activity.java:5304)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.access$1000(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5291)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: org.bytedeco.javacpp.avutil
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:251)
at org.bytedeco.javacpp.Loader.load(Loader.java:585)
at org.bytedeco.javacpp.Loader.load(Loader.java:530)
at org.bytedeco.javacpp.avcodec$AVPacket.<clinit>(avcodec.java:1694)
at org.bytedeco.javacv.FFmpegFrameRecorder.<init>(FFmpegFrameRecorder.java:149)
at com.fs.fs.api.VideoService.startRecordVideo(VideoService.java:34)
at com.fs.fs.activity.MainActivity.onCreate(MainActivity.java:75)
at android.app.Activity.performCreate(Activity.java:5304)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.access$1000(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5291)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoClassDefFoundError: org/bytedeco/javacpp/avutil
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:251)
at org.bytedeco.javacpp.Loader.load(Loader.java:585)
at org.bytedeco.javacpp.Loader.load(Loader.java:530)
at org.bytedeco.javacpp.avcodec$AVPacket.<clinit>(avcodec.java:1694)
at org.bytedeco.javacv.FFmpegFrameRecorder.<init>(FFmpegFrameRecorder.java:149)
at com.fs.fs.api.VideoService.startRecordVideo(VideoService.java:34)
at com.fs.fs.activity.MainActivity.onCreate(MainActivity.java:75)
at android.app.Activity.performCreate(Activity.java:5304)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.access$1000(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5291)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.bytedeco.javacpp.avutil" on path: DexPathList[[zip file "/data/app/com.fs.fs-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.fs.fs-2, /vendor/lib, /system/lib, /data/datalib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:251)
at org.bytedeco.javacpp.Loader.load(Loader.java:585)
at org.bytedeco.javacpp.Loader.load(Loader.java:530)
at org.bytedeco.javacpp.avcodec$AVPacket.<clinit>(avcodec.java:1694)
at org.bytedeco.javacv.FFmpegFrameRecorder.<init>(FFmpegFrameRecorder.java:149)
at com.fs.fs.api.VideoService.startRecordVideo(VideoService.java:34)
at com.fs.fs.activity.MainActivity.onCreate(MainActivity.java:75)
at android.app.Activity.performCreate(Activity.java:5304)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.access$1000(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5291)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
So I want to know a comfortable method to achieve my goal : recode video quiet and without preview. And Live real time ?
I found ffmpeg4android is a prefect library to run ffmpeg command. I just use it to compress videos from MediaRecorder But I don't how to do use it to achieve my goal.
Related
SDK Version : 29
dji SDK Version : 4.12
implementation 'com.dji:dji-sdk:4.12', {
exclude module: 'library-anti-distortion'
exclude module: 'fly-safe-database'
}
compileOnly 'com.dji:dji-sdk-provided:4.12'
And I get that error :
AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.i_ron, PID: 15818
java.lang.NoClassDefFoundError: Failed resolution of: Ldji/sdk/sdkmanager/BluetoothProductConnector;
please help me I need to be hurry for this project.
The error suggests that you have not called com.secneo.sdk.Helper.install(context).
This is usually done in an override of Application class. You also need to indicate the new application class override in the manifest.
Look at the sample app:
<application
android:name=".internal.controller.DJISampleApplication"
and in the Application override:
public class DJISampleApplication extends MultiDexApplication {
protected void attachBaseContext(Context paramContext) {
super.attachBaseContext(paramContext);
MultiDex.install(this);
com.secneo.sdk.Helper.install(this);
app = this;
}
The code is very simple, just open a picture.
But when I run this I have an error like this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.opencv.imgcodecs.Imgcodecs.imread_1(Ljava/lang/String;)J
at org.opencv.imgcodecs.Imgcodecs.imread_1(Native Method)
at org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:112)
According to the searched solution, I add this System.load(Core.NATIVE_LIBRARY_NAME) to the main(), doesn't work:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java401
at java.lang.Runtime.load0(Runtime.java:806)
at java.lang.System.load(System.java:1086)
Or this System.loadLibrary(Core.NATIVE_LIBRARY_NAME), still not work:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java401 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
My project is build by gradle, the dependencies is (official doc):
compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.5'
Thank you for your help.
Self answer.
My import is wrong. It should be
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread
instead of
import static org.opencv.imgcodecs.Imgcodecs.imread
This error caused the wrong package to be used.
The correct code is:
import org.bytedeco.opencv.opencv_core.Mat;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
public class DemoApplication {
public static void main(String[] args) {
Mat image = imread("/root/test.png");
System.out.println("width:" + image.cols());
System.out.println("height:" + image.rows());
}
}
I am using dropwizard 1.2.4 with log4j 1.2.17. I have followed the instructions as mentioned below
https://github.com/arteam/dropwizard-nologback/
It is throwing the exception like below during unit testing.
java.lang.NoClassDefFoundError: ch/qos/logback/core/filter/Filter
at io.dropwizard.testing.junit.ResourceTestRule.<clinit>(ResourceTestRule.java:34)
at com.vnera.restapilayer.api.resources.ApiInfoControllerTest.<clinit>(ApiInfoControllerTest.java:25)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:156)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1088)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1069)
at java.lang.reflect.Field.get(Field.java:393)
at org.junit.runners.model.FrameworkField.get(FrameworkField.java:73)
at org.junit.runners.model.TestClass.getAnnotatedFieldValues(TestClass.java:230)
at org.junit.runners.ParentRunner.classRules(ParentRunner.java:255)
at org.junit.runners.ParentRunner.withClassRules(ParentRunner.java:244)
at org.junit.runners.ParentRunner.classBlock(ParentRunner.java:194)
at org.junit.runners.ParentRunner.run(ParentRunner.java:362)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.core.filter.Filter
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 19 more
My test code looks like below
import io.dropwizard.testing.junit.ResourceTestRule;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import javax.ws.rs.core.Response;
import static org.mockito.Mockito.mock;
#Category(value = UnitTest.class)
public class ApiInfoControllerTest {
private static ApiNonFunctionalHandler nonFunctionalHandler = mock(ApiNonFunctionalHandler.class);
private static ApiFilter apiFilter = new ApiFilter(nonFunctionalHandler);
private static final String authToken = "NetworkInsight xTyAGJmZ8nU8yJDP7LnA8Q==";
#ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new ApiInfoController())
.addProvider(apiFilter).build();
#Test
public void testApiVersion() throws Exception {
Response response = resources.client()
.target(ApiConstants.INFO_BASE_URL + "/version")
.request()
.header("Authorization", authToken)
.buildGet().invoke();
Assert.assertNotNull(response);
Assert.assertEquals(response.toString(), Response.Status.OK.getStatusCode(), response.getStatus());
final VersionResponse actualError = response.readEntity(VersionResponse.class);
Assert.assertEquals(actualError.getApiVersion(), ApiConstants.API_VERSION);
}
}
My main application is working fine. The configuration.yaml for main application looks like below
# Change default server ports
server:
applicationConnectors:
- type: http
port: 8123
adminConnectors:
- type: http
port: 8124
requestLog:
type: external
logging:
type: external
Can someone let me know what could be going wrong and how can I get around this?
EDIT
Output of mvn dependency:tree is placed here as I am hitting the character limit here.
This is a bug in dropwizard 1.2.4 as discussed below
https://github.com/dropwizard/dropwizard/pull/2338
I'm trying to get simple example of springboot and camel working but come undone. Not sure what i'm doing wrong. in the gradle build i've included so far
dependencies {
compile 'org.apache.camel:camel-spring-boot-starter:2.18.4'
compile 'org.apache.camel:camel-groovy:2.18.4'
compile 'org.apache.camel:camel-stream:2.18.4'
compile 'org.codehaus.groovy:groovy-all:2.4.11'
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
i've create a DirectRoute component like this
#Component
class DirectRoute extends RouteBuilder{
#Override
void configure () throws Exception {
from ("direct:in") //tried stream:in also
.to ("stream:out")
}
}
I then have a driver bean that try's to invoke the route
#Component
public class HelloImpl implements Hello {
#Produce(uri = "direct:in")
private ProducerTemplate template;
#Override
public String say(String value) throws ExecutionException, InterruptedException {
assert template
println "def endpoint is : " + template.getDefaultEndpoint()
return template.sendBody (template.getDefaultEndpoint(), value)
}
}
lastly in the springboot application class i added a command line runner like this, that gets my bean from the spring context, and invokes the say method. I'm using groovy so i just passed a closure to the command line runner.
#Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
//return closure to run on startup - just list the beans enabled
{args ->
println("Let's inspect the beans provided by Spring Boot:")
String[] beanNames = ctx.getBeanDefinitionNames()
Arrays.sort(beanNames)
for (String beanName : beanNames) {
println(beanName)
}
println("call the direct:start route via the service")
Hello service = ctx.getBean("helloService")
def result = service.say("William")
println "service returned : $result "
}
}
when i run my application i get all the bean names printed out (that's ok), however when i invoke the direct:in via producer template i get this error (org.apache.camel.component.direct.DirectConsumerNotAvailableException) see below.
I was expecting the route to be triggered the name sent to see that arrive in the output stream - but this is what i get.
Caused by: org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[ID-MONSTER-PC2-58911-1496920205300-0-2]
at org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1795) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.util.ExchangeHelper.extractResultBody(ExchangeHelper.java:677) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:515) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:511) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:163) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.ProducerTemplate$sendBody$0.call(Unknown Source) ~[na:na]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) [groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) [groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) [groovy-all-2.4.11.jar:2.4.11]
at services.HelloImpl.say(HelloImpl.groovy:29) ~[main/:na]
at services.Hello$say.call(Unknown Source) ~[na:na]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) [groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) [groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) [groovy-all-2.4.11.jar:2.4.11]
at application.Application$_commandLineRunner_closure1.doCall(Application.groovy:47) ~[main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) ~[groovy-all-2.4.11.jar:2.4.11]
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) ~[groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) ~[groovy-all-2.4.11.jar:2.4.11]
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) ~[groovy-all-2.4.11.jar:2.4.11]
at groovy.lang.Closure.call(Closure.java:414) ~[groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54) ~[groovy-all-2.4.11.jar:2.4.11]
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124) ~[groovy-all-2.4.11.jar:2.4.11]
at com.sun.proxy.$Proxy44.run(Unknown Source) ~[na:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
... 10 common frames omitted
Caused by: org.apache.camel.component.direct.DirectConsumerNotAvailableException: No consumers available on endpoint: direct://in. Exchange[ID-MONSTER-PC2-58911-1496920205300-0-2]
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:55) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:529) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:497) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:365) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:497) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:225) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:144) ~[camel-core-2.18.4.jar:2.18.4]
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:161) ~[camel-core-2.18.4.jar:2.18.4]
What have i done wrong - and why does the producer template invocation on 'direct:in' (also tried stream in with same problem) not work? I thought that .to("stream:out") would be a consumer.
any pointers or advice gratefully received at this point
I have an update on my problems:
I had a subpackage with the application class annotated with #SpringBootApplication. So yes, unadorned it only scans subpackages.
you can add scanBasePackages= or scanBaseClasses= parameter, however when I tried doing a scan for single class, it seemed to scan the whole directory any way and grabbed the others as well.
I refactored the app to have a single root package with subpackages and elected to set the 'scanBasePakages to the new root package. but left the Application class in its own subpackage (personal preference only - documentation suggests leaving the Application in the root package)
you can now add other classes annotated with #Configuration to generate beans or use the basic #Component.
if you create Camel routes annotated with #Component they will be auto configured in the camelContext for you.
it appears by default that Spring isnt not starting the camelContext for you. When I checked the status of the context it shows as starting and not started. so in my commandLineRunner I had to start get the spring injected camelContext and had to start it myself, and exited it when I finished. I was slightly suprised as I thought SpringBootStarter would auto start the camelContext, but it appears not.
once you have Spring component scanning etc working and you start the camelContext, then problems with the org.apache.camel.component.direct.DirectConsumerNotAvailableException exception went away and things started to work - at least the baby examples I'm trying.
So revised structure now looks like this:
The revised ApplicationClass now looks like this with some simple println output to see the state of the context, and beans in the spring ctx. The helleoService bean is still the proxy I use to setup the producer template to call the DirectRoute.
package com.softwood.application
import groovy.util.logging.Slf4j
import org.apache.camel.CamelContext
import org.springframework.beans.factory.annotation.Autowired
import com.softwood.services.Hello
/**
* Created by willw on 07/06/2017.
*/
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean
#Slf4j //inject logger
#SpringBootApplication (scanBasePackages = ["com.softwood"]) //forces scan at parent
// same as #Configuration #EnableAutoConfiguration #ComponentScan with 'defaults' e.g. sub packages
public class Application {
#Autowired
ApplicationContext ctx
#Autowired
CamelContext camelContext
public static void main(String[] args) {
SpringApplication.run(Application.class, args)
}
#Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
//return closure to run on startup - just list the beans enabled
{args ->
println("Let's inspect the beans provided by Spring Boot:")
String[] beanNames = ctx.getBeanDefinitionNames()
Arrays.sort(beanNames)
for (String beanName : beanNames) {
println(beanName)
}
/* when component scan is working - bean routes are added
automatically to camel context via springBoot, however you do have to start
the camel context, yourself
*/
println "camelCtx has following components : " + camelContext.componentNames
println "camelCtx state is : " + camelContext.status
println "starting camel context"
camelContext.start()
println "camelCtx state now is : " + camelContext.status
//log.debug "wills logging call "
println("call the direct:start route via the service")
Hello service = ctx.getBean("helloService")
def result = service.say("William")
println "service returned : $result "
println "sleep 5 seconds "
sleep (5000)
println "stop camel context"
camelContext.stop()
println "camelCtx state now is : " + camelContext.status
}
}
}
That proxy is just registered as a simple bean like this in the spring context
package com.softwood.services
/**
* Created by willw on 07/06/2017.
*/
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutionException
#Component
public class HelloImpl implements Hello {
#Produce(uri = "direct:in") /* ?block=true */
private ProducerTemplate template
#Override
public String say(String value) throws ExecutionException, InterruptedException {
assert template
println "def endpoint is : " + template.getDefaultEndpoint()
//Future future = template.asyncSendBody(template.getDefaultEndpoint(), value)
//return future.get()
return template.sendBody (template.getDefaultEndpoint(), value)
}
}
The TimedRoute just sorts itself out with no template required to invoke in
package com.softwood.camelRoutes
/**
* Created by willw on 07/06/2017.
*/
import org.apache.camel.builder.RouteBuilder
import org.springframework.stereotype.Component
#Component
class TimedRoute extends RouteBuilder {
#Override
void configure () throws Exception {
from ("timer:foo")
.to ("log:com.softwood.application.Application?level=WARN")
}
}
My simple no-op file route isn't working (yet) and not sure why. I suspect I've not got the file config right somehow; some playing is required.
package com.softwood.camelRoutes
import org.apache.camel.builder.RouteBuilder
import org.springframework.stereotype.Component
/**
* Created by willw on 08/06/2017.
*/
#Component
class FileNoOpRoute extends RouteBuilder{
#Override
void configure () throws Exception {
from ("file:../com.softwood.file-inbox?recursive=true&noop=true&idempotent=true")
.to ("file:../com.softwood.file-outbox")
}
}
However the basics are not working and least camel is doing something whereas before I just had the exception and nothing.
I have found another question on Spring config highlighting some of the above also.
I am working my way through a Spring tutorial, I have the following code, using Java based configuration, that isn't working. In my classpath I have the Spring 3.1 jars, as well as asm-4.0.jar and cglib-2.2.2.jar.
MainApp.java:
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(
HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
}
HelloWorldConfig.java:
package com.tutorialspoint;
import org.springframework.context.annotation.*;
#Configuration
public class HelloWorldConfig {
#Bean
public HelloWorld helloWorld() {
return new HelloWorld();
}
}
HelloWorld.java:
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message) {
this.message = message;
}
public void getMessage() {
System.out.println("Your Message : " + message);
}
}
Error code:
Exception in thread "main" java.lang.IllegalStateException: Cannot load configuration class: com.tutorialspoint.HelloWorldConfig
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:456)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigurationClasses(ConfigurationClassPostProcessor.java:202)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:176)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:604)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:437)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:68)
at com.tutorialspoint.MainApp.main(MainApp.java:8)
Caused by: java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at net.sf.cglib.core.AbstractClassGenerator.<init>(AbstractClassGenerator.java:38)
at net.sf.cglib.core.KeyFactory$Generator.<init>(KeyFactory.java:127)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:112)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
at org.springframework.context.annotation.ConfigurationClassEnhancer.newEnhancer(ConfigurationClassEnhancer.java:101)
at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:89)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:448)
... 6 more
I changed the asm jar file from asm-4.0.jar to asm-3.3.jar, and it worked. There must have been a conflict between the first asm jar and the cglib jar I was using.
I was using cglib-2.1_3.jar and asm 3.1.jar when I ran in to this problem for the first time. After I removed the asm 3.1.jar and added asm- 1.5.3.jar it started working.
I was use cglib-2.1_3.jar and asm- 1.5.3, after using this jar my program run successfully.
ASM Core » 1.5.3
cglib-2.1_3.jar
Just adding this answer in case someone runs into the weird corner case issue I experienced.
This can also happen when the Jar file isn't properly signed.