Manifesto.mf errado no IntelliJ IDEA criado .jar

102

Estou tentando empacotar um projeto usando as bibliotecas do OptaPlanner 6.0.1 em um .jar por meio do artefato jar do IntelliJ IDEA, mas em vez do meu manifest.mf contendo o padrão

Manifest-Version: 1.0
Main-Class: a.b.c.app

o jar usa aquele fornecido em ecj-3.7.2.jar, uma das bibliotecas de suporte do OptaPlanner:

Manifest-Version: 1.0
Build-Jdk: 1.6.0_26
Built-By: ibrandt
Created-By: Apache Maven
Archiver-Version: Plexus Archiver

Por isso, "no main manifest attribute, in appname.jar"ocorre um erro ao tentar executar o aplicativo. Se eu substituir manualmente o manifesto no arquivo .jar pelo meu, tudo funcionará corretamente. Posso fazer alguma coisa para consertar isso?

Eu mantenho as bibliotecas em um diretório / lib separado e elas foram adicionadas à raiz do artefato jar como diretório extraído, IntelliJ IDEA é v13.0.1.

rancor
fonte
1
Você sabe construir ferramentas como formiga, maven ou gradle?
MariuszS
Eu sei sobre eles, mas até agora usei apenas contrapartes make e .NET (NAnt, MSBuild). Qual deles devo escolher se a ferramenta de construção do IntelliJ não vai funcionar?
grudolf
1
Vote para corrigir este problema aqui ,
bigjosh

Respostas:

260

Eu tive o mesmo problema.

Certifique-se de que seu MANIFEST.MF esteja em:

src/main/resources/META_INF/

NÃO

src/main/java/META_INF/
Jamhan
fonte
20
Esta é a resposta correta, de fato, parece que o Intellij IDEA está perdendo a pasta META-INF quando o modelo de projeto é Maven
Kumait
No meu caso, tive que mudar o layout do meu projeto. Eu já tinha um projeto com layout do maven, mas removi o suporte do maven. Recrio um projeto do zero e agora funciona.
Maxence
1
Isso não estava funcionando para mim, eu tive que mover o arquivo Mainfest para a raiz do projeto.
corrida de
O maven é tão estúpido que coloca esse arquivo no diretório errado? : ^)
Daria
@Kumait, o problema ainda está lá no IntelliJ 2017.1.5. Estou me perguntando se a equipe JetBrain está ciente disso.
fruqi de
12

Consertar:

  1. Arquivo> Estrutura do Projeto
  2. Em Configurações do projeto à esquerda, selecione "Artefatos"
  3. Encontre a definição JAR no painel do meio e selecione-a
  4. No painel esquerdo da guia "Layout de saída", encontre o arquivo jar na lista e selecione-o
  5. Na parte inferior, clique no botão "Usar manifesto existente" e selecione o arquivo de manifesto que está na origem do projeto.
  6. Clique em OK e execute o build
Javaru
fonte
3
Não há botão "Usar manifesto existente", no entanto, o arquivo de manifesto no layout de saída está apontando para o local correto (... \ src \ main \ java \ META-INF \ MANIFEST.MF)
grudolf
5
OK, tive que excluir o artefato jar e recriá-lo, desta vez como "Vazio" em vez de "Dos módulos com dependências". Peguei os botões "Criar Manifesto" e "Usar Manifesto Existente", apontou para o meu Manifesto e readicionei as bibliotecas e compilou a saída. Existem duas diferenças em relação a antes: um META_INF \ MANIFEST.INF agora está explicitamente incluído no layout de saída e o arquivo jar parece ter sido gerado corretamente. :)
grudolf
Isso não resolve o problema, pelo menos para mim. A resposta de Jamahn funcionou, no entanto.
Andrew Breksa
Comentário adicionado do usuário de baixa reputação @ ds-justice como segue - o comentário de @grudolf acima sobre a criação de um Jar vazio foi a única coisa que funcionou para mim depois de várias horas lutando com um projeto importado do Gradle. Esta é uma pergunta importante, por favor, considere reenviar seu comentário como uma resposta separada.
Shawn Mehan
10

Conforme observado no comentário de @grudolf em uma das outras respostas, uma maneira de fazer isso (e a única que funcionou para mim em um projeto importado do Gradle) é criar um frasco vazio da seguinte maneira:

  • Estrutura do Projeto -> Artefatos -> + Frasco -> Vazio
  • O painel central agora tem os botões Criar Manifesto e Usar Manifesto Existente. Use um destes.
  • Tive dificuldade se extraísse as bibliotecas dependentes com seus próprios manifestos na raiz de saída; elas pareciam substituir de forma intermitente o novo manifesto criado manualmente. Mexer com a ordem das operações parecia fazer funcionar.

ATUALIZAR:

Esse é definitivamente um bug do Idea. Essa resposta vinculada funciona de maneira confiável quando há diretórios extraídos. Em essência, você encontra seu .idea / JARNAME.xml, adicione o seguinte elemento ao topo do <root>elemento para seu jar. Quaisquer elementos extraídos acima de sua nova cópia de arquivo que contenham um manifesto afetarão seu novo manifesto.

  <element id="directory" name="/META-INF">
    <element id="file-copy" path="$PROJECT_DIR$/modulename/src/META-INF/MANIFEST.MF" />
  </element>
Outono
fonte
7

Se você deseja especificar a classe principal, você deve adicionar este plugin a pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>Form</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>
usbo
fonte
1

Eu tive um problema parecido.

O problema estava no arquivo pom.xml.

<archive>
  <manifestEntries>
    <Dependencies>one.jar,
                  two.rar, 
                  other.jar
    </Dependencies>
  </manifestEntries>
</archive>

Não sei por que razão este código funciona no eclipse, mas não no IntelliJ

Isso está correto.

<archive>
  <manifestEntries>
    <Dependencies>one.jar, two.rar, other.jar</Dependencies>
  </manifestEntries>
</archive>

Manifest.mf funcionou !!!

Eu espero que isso ajude.

marcelocesar
fonte
Eu tive essa situação exata e cheguei à mesma conclusão que você: novas linhas entre itens <Dependencies> funcionaram no Eclipse, mas não no Intellij IDEA.
Arion Krause
0

Existem várias maneiras de gerar jars executáveis. Usar o recurso GUI do IntelliJ é uma boa maneira. Outra maneira é usar o Maven (ou similarmente no gradle, buildr, etc), que é amigável ao servidor de compilação:

É mais ou menos copiável e colável da compilação do maven de exemplos do optaplanner:

  1. O jar do usuário final (optaplanner-examples - *. Jar) deve incluir o caminho de classe de suas dependências em seu manifesto .
  2. O script sh e bat deve, então, executar esse jar de acordo.
Geoffrey De Smet
fonte
0

Para não ter problemas como o Manifest, você deve ter um diretório chamado "META-INF" no diretório "src". Portanto, crie-o e coloque nele um arquivo chamado "MANIFEST.MF" com o seguinte conteúdo:

Manifest-Version: 1.0
Main-Class: <packageName>.Main

Não se esqueça de substituir o nome do pacote que contém a classe principal acima!

Mohsen Abasi
fonte
4
O registro mostra que cortei material religioso de sua postagem em agosto. Observe que a comunidade discutiu a adição de temas religiosos às postagens e a resposta é que preferiríamos que eles fossem deixados de fora. No entanto, você está convidado a adicioná-los ao seu perfil ou avatar.
meia