mybatis / guice

Google Guice integration for MyBatis 3
http://mybatis.github.io/guice
Apache License 2.0
175 stars 118 forks source link

Before packaging into a jar, the program runs normally in IDEA. However, after packaging with the maven-shade-plugin, an exception occurs during execution. I used jd-gui to decompile the jar, and both the mapper class and mapper.xml are present. Below are the related programs and the exception that occurs after running. Could you help me figure out what is causing this issue? #745

Open LetAmericaGreatAgain opened 2 months ago

LetAmericaGreatAgain commented 2 months ago

Before packaging into a jar, the program runs normally in IDEA. However, after packaging with the maven-shade-plugin, an exception occurs during execution. I used jd-gui to decompile the jar, and both the mapper class and mapper.xml are present. Below are the related programs and the exception that occurs after running. Could you help me figure out what is causing this issue?

import com.google.inject.PrivateModule; import com.google.inject.Scopes; import com.google.inject.name.Names; import com.ultimate.cas.sso.server.service.IUserService; import com.ultimate.cas.sso.server.service.impl.UserServiceImpl; import org.mybatis.guice.XMLMyBatisModule;

public class MybatisModule extends PrivateModule { @Override protected void configure() { install(new XMLMyBatisModule() {

        @Override
        protected void initialize() {
            setEnvironmentId("mysql");
            setClassPathResource("mybatis-config-mysql.xml");
            bind(IUserService.class).annotatedWith(Names.named("mysql")).to(UserServiceImpl.class).in(Scopes.SINGLETON);
        }
    });
    expose(IUserService.class).annotatedWith(Names.named("mysql"));
}

} image

LetAmericaGreatAgain commented 2 months ago

image

hazendaz commented 2 months ago

This is long but I see you are fairly new to github and doing some things that are not very helpful for you to succeed, so I'm going to try to help as much as I can here so bare with me.

I did close all your other tickets. Please do not use intellij to submit tickets, its spamming nature and poor ticket creation is not worth it. Also don't open your open tickets in same manner. Come here directly, open a ticket and add all information to one ticket only. Always make sure your info is not just screen shots as no one can search for those if running into same issues. The data listed is critical for helping not only you but other users that might run into same issue. We need to know more information too. What version did you even use of mybatis guice, mybatis, jvm, maven version, shading plugin version, etc. It all matters.

Now, never use the shade maven plugin for complex stuff, especially in the case you are trying to use it. Its generally meant to shade a single jar such as ASM where you need a specific version for your product but want to allow users of your product to use other versions. Its not generally meant to take every library you want to use and squash them all into a single jar (ie uber jar). All that does is breaks the metadata and would tell you this during build as maven will echo warnings with issues from logging, to security, etc. Some jars cannot be shaded (bouncy castle for example) as it will entirely break the logic with security requirements of the jvm. Others, specifically some injection frameworks cannot handle being shaded due to how they look things up which become broken in that state.

Additionally, de-compiling a jar should be done by tools that support newer jdks so you get better results. We require java 17 or better here. Jd-gui is not supported any more nor does it support all parts of java up that high. While it appears they tried to bring it back in 2019, that was 5 years ago and the issues list seems to indicate it has issues from lambdas from java 8 still and there have been zero commits since. There are far better de-compilers out there that support all the way to java 21 or better. That really has no need to be even mentioned here though. We are not the shade maven plugin so its behaviour or content via a de-compiler mean nothing here. We are a product for mybatis integration with guice only and unless documented otherwise we would not expect nor support such usage. If you really have concerns over what shading does, open ticket with maven and/or read their documentation of it to better understand its use-case. But again don't use that plugin for your use case. And its also not an issue with their plugin.

Now, it appears you are trying to create a single jar to do something. When you are sitting in an IDE, the code is NOT compressed into a JAR. There is a 100% difference between the IDE and the final artifact usage. In fact you did not even using shading in the IDE. That was done when you built it to the final jar. Anyway, use a better tool. Use spring boot! Spring boot can wrap anything. You don't need to add anything spring either. Using spring boot will get you what you want as it will not touch the jars and add them to boot-inf/lib folder. You still get a single JAR in the end and if you use the scripting method of building it via their plugin, you get the bonus of not having to run java -jar xxx but rather just execute the jar directly. Even further, if you are wanting to run only on windows, you can use tools that take that final result and bundle that into a windows EXE so its just a double click event to start. Now, if there are any JARS such as bouncy castle that hate that or some injection frameworks that don't like the URL management there either (cdi weld for example), spring boot offers options. You can tell it via the spring boot maven plugin what JARS you want extracted out to the temp folder during your product run so that they run exactly how java expects them to. That allows the app to run as designed and still achieves what you are trying to do, a single JAR delivery.

Others might chime in with other thoughts but I think the main result here is that this is unlikely a problem with this library. However, if you still feel that it is, keep to this single ticket instead of opening more. Please do adjust this title as well so its readable. And lets say you take this advice and you get a successfully working single jar using spring boot with this, please don't hesitate to follow up by updating our documentation via a PR showing others how to achieve that. FWIW I've done this with 20 year old java products with spring boot 2 and 3 without having to support anything of spring thus why I know this is viable in this situation.

LetAmericaGreatAgain commented 2 months ago

This is long but I see you are fairly new to github and doing some things that are not very helpful for you to succeed, so I'm going to try to help as much as I can here so bare with me.

I did close all your other tickets. Please do not use intellij to submit tickets, its spamming nature and poor ticket creation is not worth it. Also don't open your open tickets in same manner. Come here directly, open a ticket and add all information to one ticket only. Always make sure your info is not just screen shots as no one can search for those if running into same issues. The data listed is critical for helping not only you but other users that might run into same issue. We need to know more information too. What version did you even use of mybatis guice, mybatis, jvm, maven version, shading plugin version, etc. It all matters.

Now, never use the shade maven plugin for complex stuff, especially in the case you are trying to use it. Its generally meant to shade a single jar such as ASM where you need a specific version for your product but want to allow users of your product to use other versions. Its not generally meant to take every library you want to use and squash them all into a single jar (ie uber jar). All that does is breaks the metadata and would tell you this during build as maven will echo warnings with issues from logging, to security, etc. Some jars cannot be shaded (bouncy castle for example) as it will entirely break the logic with security requirements of the jvm. Others, specifically some injection frameworks cannot handle being shaded due to how they look things up which become broken in that state.

Additionally, de-compiling a jar should be done by tools that support newer jdks so you get better results. We require java 17 or better here. Jd-gui is not supported any more nor does it support all parts of java up that high. While it appears they tried to bring it back in 2019, that was 5 years ago and the issues list seems to indicate it has issues from lambdas from java 8 still and there have been zero commits since. There are far better de-compilers out there that support all the way to java 21 or better. That really has no need to be even mentioned here though. We are not the shade maven plugin so its behaviour or content via a de-compiler mean nothing here. We are a product for mybatis integration with guice only and unless documented otherwise we would not expect nor support such usage. If you really have concerns over what shading does, open ticket with maven and/or read their documentation of it to better understand its use-case. But again don't use that plugin for your use case. And its also not an issue with their plugin.

Now, it appears you are trying to create a single jar to do something. When you are sitting in an IDE, the code is NOT compressed into a JAR. There is a 100% difference between the IDE and the final artifact usage. In fact you did not even using shading in the IDE. That was done when you built it to the final jar. Anyway, use a better tool. Use spring boot! Spring boot can wrap anything. You don't need to add anything spring either. Using spring boot will get you what you want as it will not touch the jars and add them to boot-inf/lib folder. You still get a single JAR in the end and if you use the scripting method of building it via their plugin, you get the bonus of not having to run java -jar xxx but rather just execute the jar directly. Even further, if you are wanting to run only on windows, you can use tools that take that final result and bundle that into a windows EXE so its just a double click event to start. Now, if there are any JARS such as bouncy castle that hate that or some injection frameworks that don't like the URL management there either (cdi weld for example), spring boot offers options. You can tell it via the spring boot maven plugin what JARS you want extracted out to the temp folder during your product run so that they run exactly how java expects them to. That allows the app to run as designed and still achieves what you are trying to do, a single JAR delivery.

Others might chime in with other thoughts but I think the main result here is that this is unlikely a problem with this library. However, if you still feel that it is, keep to this single ticket instead of opening more. Please do adjust this title as well so its readable. And lets say you take this advice and you get a successfully working single jar using spring boot with this, please don't hesitate to follow up by updating our documentation via a PR showing others how to achieve that. FWIW I've done this with 20 year old java products with spring boot 2 and 3 without having to support anything of spring thus why I know this is viable in this situation.

Thank you very much for your suggestion. It’s true that using Maven Shade to package Bouncy Castle causes issues. Spring Boot's integration with MyBatis is not flexible enough, while Guice-MyBatis offers greater flexibility in database control, thanks to some features of Guice. Regarding the current issue, I still believe it is related to the framework. I have regenerated the JAR using the Maven JAR Plugin and Maven Dependency Plugin, and confirmed that bulk importing the mapper interface classes and XML files by package name fails to run after packaging. However, importing them individually via fully qualified class names or paths works without any issues. I’d like to know your thoughts on this