Adding custom jars to camel-k integration - kubernetes

Lets say I have utility jar called validation.jar
which can validate some string to be forwarded.
How can I add this validation.jar along with camel-k integration in minkube.
example :
import com.validation.Util;
import org.apache.camel.builder.RouteBuilder;
public class MyRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
//from("timer:tick").log(Util.validate("dummy message - new"));
from("timer:tick").log("dummy message - new");
}
}
to get com.validation.Util class we need validation.jar available with camel-k. How to provide that.

There is just one way of achieving your goal. Store your java classses with pom.xml file for building jar in github repository. After that you can use Jitpack.io. Jitpack will build and store jar file in its registry. Finally, you can use as dependency on kamel run command.

Starting from camel-k 1.9.x, it is possible to provide a dependency located in the local filesystem by using the file:// prefix when specifying the dependency, like the next example:
kamel run -d file://path/to/validation.jar MyRoute.java

Related

Could not find main method from given launch configuration

I've a simple Java project that works when I execute it at Eclipse environment. But when I try to export it to a Runnable Jar, I get the following error:
JAR export finished with warnings. See details for additional information.
Exported with compile warnings: JavaSwing/src.main.java/com/cansoft/GUIProgram.java
Exported with compile warnings: JavaSwing/src.main.java/com/util/Util.java
Jar export finished with problems. See details for additional information.
Could not find main method from given launch configuration.
I read other posts which suggest to create a MANIFEST.MF file specifying the main-class which I did. It is placed at MyProjectFolder/META-INF/MANIFEST.MF and it contains the following information:
Manifest-Version: 1.0
Class-Path: resources
main-class: com.cansoft.GUIProgram
My main class is as follows:
public class GUIProgram {
private JFrame folderCreationSubappFrame;
private Color color;
private String home;
private final static Logger LOG_MONITOR = Logger.getLogger("com.cansoft");
public static void main(String[] args) {
try {
new GUIProgram();
} catch (Exception e) {
LOG_MONITOR.log(Level.INFO,e.getMessage());
}
}
public GUIProgram() throws InterruptedException, SecurityException, IOException {
home = System.getProperty("user.home") + File.separator + "Documents";
startLogSystem();
if(isFirstRun()) {
showWelcomeFrame();
} else {
initialize();
}
} .... More and more code
Does anybody know what am I missing? Any help much appreciated.
Thank you.
It is not enough to create the manifest file, you need to explicitly choose it in the Eclipse jar export dialog.
Answer to Comment
If you use "runnable jar", make sure that you chose the correct launch configuration and that the launch configuration successfully runs when chosing "Run As" -> "Run Configurations" -> "Java Application" -> Your Configuration -> "Run"
I finally find out where the problem was, it was quite simple btw. I had created my GUIProgram within a src.main.java package, but that package was created (my bad) as resources instead of folders, so Eclipse was smart enought to run it but when trying to generate the JAR which expected a correct java project structure, it was failing because truly there were not GUIProgram java class at src path (src was not folder type but resources).
Hope I succeed explaining.

Keycloak Userstorage SPI: Provider not found?

What are the requirments to make the Keycloak 17.0.0 find the provider?
[error]: Build step org.keycloak.quarkus.deployment.KeycloakProcessor#configureProviders threw an exception: java.util.ServiceConfigurationError: org.keycloak.storage.UserStorageProviderFactory: Provider my.own.package.UserStorageProviderFactoryImpl not found
If I clone the project from baeldung and I start the keycloak, it works. It finds the provider. (https://www.baeldung.com/java-keycloak-custom-user-providers)
As I see the followings have to happen to make it work:
have a class that implements the UserStorageProviderFactory interface:
public class UserStorageProviderFactoryImpl implements UserStorageProviderFactory<MyImplementation> {}
create the META-INF and services folders and create the org.keycloak.storage.UserStorageProviderFactory file that contains the path to given factory:
mvn clean package --> copy jar to Keycloak/providers and should work
What do I miss? What is extra in the baeldung project that make it work while my project is not found when I start the keycloak?
https://www.keycloak.org/docs/latest/server_development/index.html#_user-storage-spi
Your class should be name SomethingUserStorageProviderFactory without the word 'impl'. Your provider class should have the same pattern name, for example, SomethingUserStorageProvider.
Official documentation gives more interesting information’s (https://www.keycloak.org/docs/latest/server_development/#_providers) and if you take a look at baeldung's code, he due the same pattern name.

dagger android support to androidx.fragment

How to inject a fragment from the package androidx.fragment.app.Fragment ?
I'm using the dagger-android framework to inject my dependencies in my code.
As the documentation says I do this to inject my fragment
#Override
public void onAttach(Activity activity) {
AndroidInjection.inject(this);
super.onAttach(activity);
// ...
}
the problem is that AndroidSupportInjection class accept only fragments of the package android.support.v4.app.Fragment or if I use AndroidInjection class only accept fragments of the package android.app.Fragment and I want to use fragments of the androidx.fragment.app.Fragment package.
Also DaggerFrament extend from android.support.v4.app.Fragment and want to use a fragment from androidx
And If I try to implement HasSupportFragmentInjector also this interface use a fragment from android.support
add the below code to your gradle.properties
android.useAndroidX=true
android.enableJetifier=true
And if you are trying to inject into a Fragment you have to replace AndroidInjection.inject(this) with AndroidSupportInjection.inject(this)
I had the same problem in case of HasFragmentInjector. You need to use HasSupportFragmentInjector for fragment injection. This is because, HasFragmentInjector uses android.app.Fragment which is not effected by jetifier. You need to add android-dagger-support library, jetifier converts all the support packages to androidx in Studio 3.3 (if jetifier is enabled).
If jetifier does not change support packages to androidx packages. You can download jetifier tool from here and convert the android-dagger-support.aar file manually by using the following command.
./jetifier-standalone -i dagger-android-support-<version>.aar -o <output-name>
Then add the library to your project. This is the HasSupportFragment class after conversion
import androidx.fragment.app.Fragment;
import dagger.android.AndroidInjector;
public interface HasSupportFragmentInjector {
AndroidInjector<Fragment> supportFragmentInjector();
}
Somehow, jetifier tool was not converting libraries in AndroidStudio.
I had to do it manually.
I had a similar error and it was due to the Dagger version. On version 2.17 there is an strange issue, but if you roll back to version 2.16 it compiles perfectly (apart from the flags on gradle.properties that Paul posted).
From there using the tutorials you won't have trouble. Forgot to mention that on my project I had the non-androidX version of everything, then I ran the androidX migration that android studio offers, and after that I had to switch the Dagger version, but I suppose that if you do it from the start it's the same.
Hope this helps, if you switch and it doesn't work, post a little bit of your dagger implementation and plugins versions and I will try to help more!
Add the following to your gradle.properties file
android.useAndroidX = true
android.enableJetifier = true
Just for reference. i had the same problem. It was Jetifier issue. please upgrade your gradle build tools plugin to 3.3.0
classpath 'com.android.tools.build:gradle:3.3.0'
Sample code: https://github.com/jega-ms/android-dagger2-mvp-rx
This is what I did to work with androidx namespace for Dagger 2.21
Downloaded the jetifier tool from here: https://developer.android.com/studio/command-line/jetifier
Unzip into a folder and open a terminal pointing into the extracted bin folder
From Android Studio, open a class like DaggerFragment to check the path where the file is stored, for me (in MacOS) is something like this:
From terminal execute this command (replacing with the correct variables and path)
./jetifier-standalone -i /Users/{YOUR_USER}/.gradle/caches/{PATH_TO_DAGGER_ANDROID_SUPPORT_FOLDER}/dagger-android-support-2.21.aar -o dagger-android-support-2.21.aar
The converted dagger-android-support-2.21.aar will appear in your bin folder
Now open your app build.gradle file and change this line
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
adding the , '*.aar' part in the include array
Move the generated dagger-android-support-2.21.aar from bin to libs folder inside your project.
Remove (or comment) this line from the dependencies
implementation "com.google.dagger:dagger-android-support:2.21
Now you can proceed invalidating the cache and rebuild the project and now DaggerFragment will point to your converted version which uses androidx.fragment.app.Fragment
NOTE: Obviously this is a temporary workaround and you should move to the official version as soon this is fixed in Dagger
The solution to my particular problem was to use android dagger classes as interfaces instead of extend of them:
class MyFragment() : HasSupportFragmentInjector {
#Inject
lateinit var childFragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return childFragmentInjector
}
........
}
To my Activities
class MyActivity : HasSupportFragmentInjector {
#Inject
internal lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentInjector
......
}
and also I have this in my gradle.properties file:
android.useAndroidX = true
android.enableJetifier = true

Not able to create executable jar for webdriver+TestNg project which does not contain main method in any class

I am learning webdriver and I have created one project with TestNg.
I have several classes in my package under src folder.
No class contains public static void main(....). i.e[Entry Point]
My question is :
Can we create Runnable / Executable jar file through eclipse for projects like this[project without main method]. I searched on many sites but unfortunately didnt get solution.
Please suggest me some links OR The way by which we can do this.
To create a jar file of the TestNG without main method you have to create another class which contain main method.
Suppose you have a TestNG file name as Sample.java, in the same package create one more class as ExecutableRar and write the below code :
public class ExecutableRar {
public static void main(String[] args) {
TestNG testng = new TestNG();
Class[] classes = new Class[]{Sample.class};
testng.setTestClasses(classes);
testng.run();
}
Now you can run this class as a Java Application. Then right click on the package --> Export --> Java --> Runnable jar File --> select ExecutableRar in launch configuration --> Browse the file location and enter the name of the file in Export Destination --> Finish.
Please let me know if you are having any issues.

Wicket + Spring Boot + .war file deployment

Building on the example here: https://github.com/Pentadrago/spring-boot-example-wicket
And taking into account the jar-to-war guide here: https://spring.io/guides/gs/convert-jar-to-war/
I'd like to convert my existing Wicket + Spring (using data-jpa and security) to Spring Boot. It's been fairly easy to get the fat-jar setup to work, but it has so far proved impossible for me to convert this setup into a .war file to deploy in Tomcat.
The issue stems from the conflicting instructions to:
on the one hand extends org.springframework.boot.context.web.SpringBootServletInitializer from a non-#Configuration class for the jar-to-war conversion guide,
while on the other implements org.springframework.boot.context.embedded.ServletContextInitializer for a #Configuration marked class for the fat-jar Wicket example.
I've not been able to align the two such that I get a working application both when debugging with the embedded container, and when deployed as .war in Tomcat.
Can anyone tell me how I can setup a spring-boot enabled wicket application that I can deploy as a .war file?
What I did and got the application to work was the following:
I checked out the example project https://github.com/Pentadrago/spring-boot-example-wicket that you posted.
Then following the code on the https://spring.io/guides/gs/convert-jar-to-war/ guide all I did was to make the following changes:
Change build.gradle to:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
apply plugin: 'war'
jar {
version = '0.0.1'
}
repositories {
mavenCentral()
}
configurations {
providedRuntime
}
dependencies {
compile(
"org.springframework.boot:spring-boot-starter",
"org.springframework.boot:spring-boot-starter-logging",
"org.springframework:spring-web:4.0.3.RELEASE",
"org.apache.wicket:wicket-spring:6.15.0",
)
testCompile(
"org.springframework.boot:spring-boot-starter-test",
)
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}
Add the following class:
HelloWebXml.java
package spring.boot.example.wicket;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class HelloWebXml extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WicketWebApplication.class);
}
}
Those where the only changes I made and deployed to Tomcat 7 without any problems.
Here is the excerpt from the log that shows that wicked got started
2014-08-27 20:57:41.396 INFO 2708 --- [on(3)-127.0.0.1] org.apache.wicket.Application : [wicket-filter] init: Wicket core library initializer
I am not sure what your source of confusion is but you have to understand that SpringBootServletInitializer and ServletContextInitializer serve different purposes.